Documentation
¶
Overview ¶
Package outbox owns the database-level protocol shared by every internal change-event writer and by the visibility watermarker.
Index ¶
- Constants
- Variables
- func AcquireObservedWatermarkFence(ctx context.Context, tx pgx.Tx, observer FenceObserver) (pgx.Tx, error)
- func AcquireObservedWriterFence(ctx context.Context, tx pgx.Tx, observer FenceObserver) (pgx.Tx, error)
- func AcquireWatermarkFence(ctx context.Context, tx pgx.Tx) error
- func AcquireWriterFence(ctx context.Context, tx pgx.Tx) error
- func AfterSequenceAllocated(ctx context.Context, origin string, seq int64) error
- func ChecksKey(installationID int64, repositoryGitHubID int64, sha string) string
- func PullRequestKey(installationID int64, repositoryGitHubID int64, number int) string
- func PullRequestWorkItemKey(repositoryGitHubID int64, pullNumber int) string
- func RepoRulesKey(installationID, repositoryGitHubID int64) string
- func RepositoryKey(installationID, repositoryGitHubID int64) string
- func StackKey(installationID int64, repositoryGitHubID int64, number int) string
- func StackWorkItemKey(repositoryGitHubID int64, stackNumber int) string
- func WithSequenceAllocationHook(ctx context.Context, hook func(origin string, seq int64) error) context.Context
- type Definition
- type FenceObservation
- type FenceObserver
- type FenceRole
Constants ¶
const ( // FenceKey is a stable, database-wide advisory-lock key ("ghsync" in // ASCII). Writers hold its shared transaction lock before allocating an // outbox sequence; the watermarker briefly takes the exclusive counterpart. FenceKey int64 = 0x676873796e63 EntitiesStream = "entities" WorkItemsStream = "work_items" RepositoryChangedKind = "repository.changed" RepositoryTombstonedKind = "repository.tombstoned" PullRequestChangedKind = "pull_request.changed" PullRequestTombstonedKind = "pull_request.tombstoned" StackChangedKind = "stack.changed" StackTombstonedKind = "stack.tombstoned" ChecksChangedKind = "checks.changed" RepoRulesChangedKind = "repo_rules.changed" WorkItemChangedKind = "work_item.changed" WorkItemRemovedKind = "work_item.removed" EntityWriterOrigin = "entity_writer" DeriverOrigin = "deriver" ExclusiveWatermarkFence FenceRole = "exclusive_watermarker" )
Variables ¶
var V1Definitions = []Definition{ {EntitiesStream, RepositoryChangedKind, "repo:{installation_id}:{repo_gh_id}", "repos(installation_id,gh_id)", `{"version":1}`}, {EntitiesStream, RepositoryTombstonedKind, "repo:{installation_id}:{repo_gh_id}", "repos(installation_id,gh_id)", `{"version":1}`}, {EntitiesStream, PullRequestChangedKind, "pr:{installation_id}:{repo_gh_id}:{pr_number}", "pull_requests(repos.installation_id,repos.gh_id,number), pull_request_review_requests(repo_id,pr_number), pull_request_reviews(repo_id,pr_number), pull_request_comments(repo_id,pr_number), pull_request_change_snapshots(repo_id,pr_number), pull_request_changed_files(repo_id,pr_number), pull_request_file_owners(repo_id,pr_number)", `{"version":1}`}, {EntitiesStream, PullRequestTombstonedKind, "pr:{installation_id}:{repo_gh_id}:{pr_number}", "pull_requests(repos.installation_id,repos.gh_id,number), pull_request_review_requests(repo_id,pr_number), pull_request_reviews(repo_id,pr_number), pull_request_comments(repo_id,pr_number), pull_request_change_snapshots(repo_id,pr_number), pull_request_changed_files(repo_id,pr_number), pull_request_file_owners(repo_id,pr_number)", `{"version":1}`}, {EntitiesStream, StackChangedKind, "stack:{installation_id}:{repo_gh_id}:{stack_number}", "stacks(repos.installation_id,repos.gh_id,number)", `{"version":1}`}, {EntitiesStream, StackTombstonedKind, "stack:{installation_id}:{repo_gh_id}:{stack_number}", "stacks(repos.installation_id,repos.gh_id,number)", `{"version":1}`}, {EntitiesStream, ChecksChangedKind, "checks:{installation_id}:{repo_gh_id}:{head_sha}", "check_runs(repos.installation_id,repos.gh_id,head_sha)", `{"version":1}`}, {EntitiesStream, RepoRulesChangedKind, "repo_rules:{installation_id}:{repo_gh_id}", "repo_rules(repos.installation_id,repos.gh_id)", `{"version":1}`}, {WorkItemsStream, WorkItemChangedKind, "repo:{repo_gh_id}:{work_item_kind}:{number}", "work_items(identity_key)", `{"version":1,"identity_key":"<entity_key>","scope_key":"<owning_scope>"}`}, {WorkItemsStream, WorkItemRemovedKind, "repo:{repo_gh_id}:{work_item_kind}:{number}", "work_items(identity_key), absent after removal", `{"version":1,"identity_key":"<entity_key>","scope_key":"<owning_scope>"}`}, }
V1Definitions enumerates every event variant emitted by internal writers.
Functions ¶
func AcquireObservedWatermarkFence ¶ added in v0.4.1
func AcquireObservedWatermarkFence( ctx context.Context, tx pgx.Tx, observer FenceObserver, ) (pgx.Tx, error)
AcquireObservedWatermarkFence is AcquireWatermarkFence with wait/hold observation. Callers must use the returned transaction for the fenced read, publication, and Commit or Rollback.
func AcquireObservedWriterFence ¶ added in v0.4.1
func AcquireObservedWriterFence( ctx context.Context, tx pgx.Tx, observer FenceObserver, ) (pgx.Tx, error)
AcquireObservedWriterFence is AcquireWriterFence with wait/hold observation. Callers must use the returned transaction for all subsequent work so Commit or Rollback records the hold interval.
func AcquireWatermarkFence ¶
AcquireWatermarkFence waits for every registered writer transaction to end and prevents a new writer from allocating a sequence until tx commits.
func AcquireWriterFence ¶
AcquireWriterFence registers tx as an outbox writer. It must be called before tx inserts its first change_events row and remains held through commit.
func AfterSequenceAllocated ¶
AfterSequenceAllocated runs the context hook, when present.
func PullRequestKey ¶
func PullRequestWorkItemKey ¶
func RepoRulesKey ¶
func RepositoryKey ¶
func StackWorkItemKey ¶
func WithSequenceAllocationHook ¶
func WithSequenceAllocationHook( ctx context.Context, hook func(origin string, seq int64) error, ) context.Context
WithSequenceAllocationHook installs a test-only transaction pause/failure seam that runs immediately after a real change_events sequence allocation. It lives beside the fence protocol so tests cannot replace the production entity-writer or deriver transaction with a synthetic writer. C-C6 still applies: the hook may coordinate or fail a test, but must not perform network I/O while the transaction and writer fence are open.
Types ¶
type Definition ¶
type Definition struct {
Stream string
Kind string
EntityKeyGrammar string
LookupTarget string
PayloadRule string
}
Definition is one v1 event variant in the public change-stream contract. db/CONTRACT.md is schema-tested against this manifest.
type FenceObservation ¶ added in v0.4.1
type FenceObservation struct {
Role FenceRole
WaitDuration time.Duration
HoldDuration time.Duration
Acquired bool
}
FenceObservation separates time queued for the advisory lock from time the acquired transaction retained it. Acquired is false when lock acquisition failed, in which case HoldDuration is zero.
type FenceObserver ¶ added in v0.4.1
type FenceObserver interface {
OutboxFence(context.Context, FenceObservation)
}
FenceObserver receives completed C-S2 fence attempts. Implementations must not block: successful observations run immediately after Commit or Rollback.