Documentation
¶
Overview ¶
Copyright IBM Corp. All Rights Reserved. SPDX-License-Identifier: Apache-2.0
Copyright IBM Corp. All Rights Reserved. SPDX-License-Identifier: Apache-2.0
Index ¶
- Constants
- Variables
- func NewAdvisoryLockFactoryForID(lockID int64) ...
- func NewCleanupLeaderFactoryForID(lockID int64) ...
- func NewConditionInterpreter() *interpreter
- func NewNamedDriver(config driver3.Config, dbProvider fscPostgres.DbProvider) driver3.NamedDriver
- func NewPaginationInterpreter() common.PagInterpreter
- type AdvisoryLock
- type AuditTransactionStore
- func (s *AuditTransactionStore) AcquireLeadership(ctx context.Context, lockID int64) (tokensdriver.RecoveryLeadership, bool, error)
- func (s *AuditTransactionStore) ClaimPendingTransactions(ctx context.Context, params tokensdriver.RecoveryClaimParams) ([]*tokensdriver.RecoveryClaim, error)
- func (s *AuditTransactionStore) CreateSchema() error
- func (s *AuditTransactionStore) GetSchema() string
- func (s *AuditTransactionStore) ReleaseRecoveryClaim(ctx context.Context, txID string, owner string, _ string) error
- func (s *AuditTransactionStore) WriteDB() *sql.DB
- type Driver
- func (d *Driver) NewAuditTransaction(name driver2.PersistenceName, params ...string) (driver3.AuditTransactionStore, error)
- func (d *Driver) NewEndorser(name driver2.PersistenceName, params ...string) (driver3.EndorserStore, error)
- func (d *Driver) NewIdentity(name driver2.PersistenceName, params ...string) (driver3.IdentityStore, error)
- func (d *Driver) NewKeyStore(name driver2.PersistenceName, params ...string) (driver3.KeyStore, error)
- func (d *Driver) NewOwnerTransaction(name driver2.PersistenceName, params ...string) (driver3.TokenTransactionStore, error)
- func (d *Driver) NewToken(name driver2.PersistenceName, params ...string) (driver3.TokenStore, error)
- func (d *Driver) NewTokenLock(name driver2.PersistenceName, params ...string) (driver3.TokenLockStore, error)
- func (d *Driver) NewWallet(name driver2.PersistenceName, params ...string) (driver3.WalletStore, error)
- type EndorserStore
- type IdentityNotifier
- type IdentityStore
- type KeystoreStore
- type Notifier
- func (db *Notifier) Close() error
- func (db *Notifier) CreateSchema() error
- func (db *Notifier) GetSchema() string
- func (db *Notifier) ListenerError() <-chan error
- func (db *Notifier) Subscribe(callback driver.TriggerCallback) error
- func (db *Notifier) TransportError() <-chan error
- func (db *Notifier) UnsubscribeAll() error
- type PrimaryKey
- type TokenLockStore
- func (db *TokenLockStore) AcquireCleanupLeadership(ctx context.Context) (driver.CleanupLeadership, bool, error)
- func (db *TokenLockStore) Cleanup(ctx context.Context, leaseExpiry time.Duration) error
- func (s *TokenLockStore) CreateSchema() error
- func (s *TokenLockStore) GetSchema() string
- func (db *TokenLockStore) Lock(ctx context.Context, tokenID *token.ID, consumerTxID transaction.ID, ...) error
- func (db *TokenLockStore) LockBatch(ctx context.Context, tokenIDs []*token.ID, consumerTxID transaction.ID, ...) (driver.BatchLockOutcome, error)
- func (db *TokenLockStore) RoundTrips() int64
- func (db *TokenLockStore) UniqueViolations() int64
- type TokenNotifier
- type TokenStore
- type TransactionNotifier
- type TransactionStore
- func (s *TransactionStore) AcquireLeadership(ctx context.Context, lockID int64) (tokensdriver.RecoveryLeadership, bool, error)
- func (db *TransactionStore) ClaimPendingTransactions(ctx context.Context, params tokensdriver.RecoveryClaimParams) ([]*tokensdriver.RecoveryClaim, error)
- func (db *TransactionStore) CleanupExpiredClaims(ctx context.Context) (int, error)
- func (s *TransactionStore) CreateSchema() error
- func (s *TransactionStore) GetSchema() string
- func (db *TransactionStore) ReleaseRecoveryClaim(ctx context.Context, txID string, owner string, message string) error
- type WalletStore
Constants ¶
const ( // MaxLockBatchCandidates is the largest batch LockBatch accepts. Each candidate binds its // (tx_id, idx) pair, so the statement carries 2n+lockBatchFixedParameters parameters and // the protocol bound above caps n here. // // It is exported because it is a precondition on the caller, not an internal detail: a // caller that needs more tokens than this must claim them in several windows, which is // what the selector's own, far smaller, window cap does (sherdlock.maxBatchWindow). A // batch over the bound is refused with a clear error rather than passed to the driver, // where it surfaces as an opaque protocol failure - and, on the selector's store-error // path, as a refetch that rebuilds the same oversized window and burns the retry budget. MaxLockBatchCandidates = (maxBindParameters - lockBatchFixedParameters) / 2 )
Variables ¶
var ErrNotifierClosed = errors.New("notifier is closed")
ErrNotifierClosed is returned when the notifier has been closed and can no longer accept subscriptions or report listener errors.
Functions ¶
func NewAdvisoryLockFactoryForID ¶ added in v0.21.0
func NewAdvisoryLockFactoryForID(lockID int64) func(context.Context, common5.WriteDB) (tokensdriver.RecoveryLeadership, bool, error)
NewAdvisoryLockFactoryForID returns a recovery leader factory bound to lockID. Binding the id at construction keeps it out of the call path, so no caller has to know how a lock id is made unique and none can accidentally pass one that is shared with another TMS.
func NewCleanupLeaderFactoryForID ¶ added in v0.21.0
func NewCleanupLeaderFactoryForID(lockID int64) func(context.Context, common5.WriteDB) (tokensdriver.CleanupLeadership, bool, error)
NewCleanupLeaderFactoryForID returns a cleanup leader factory bound to lockID, so the id is fixed when the store is built rather than supplied per call.
func NewConditionInterpreter ¶
func NewConditionInterpreter() *interpreter
func NewNamedDriver ¶
func NewNamedDriver(config driver3.Config, dbProvider fscPostgres.DbProvider) driver3.NamedDriver
NewNamedDriver returns a NamedDriver for Postgres.
func NewPaginationInterpreter ¶
func NewPaginationInterpreter() common.PagInterpreter
Types ¶
type AdvisoryLock ¶
type AdvisoryLock struct {
// contains filtered or unexported fields
}
AdvisoryLock implements RecoveryLeadership using PostgreSQL advisory locks. Advisory locks are session-scoped and automatically released when the connection closes.
func NewAdvisoryLock ¶
func NewAdvisoryLock(ctx context.Context, db common5.WriteDB, lockID int64) (*AdvisoryLock, bool, error)
NewAdvisoryLock attempts to acquire a PostgreSQL advisory lock for the given lockID. Returns (lock, true, nil) if the lock was acquired successfully. Returns (nil, false, nil) if the lock is held by another session. Returns (nil, false, error) if an error occurred during acquisition.
The lock is session-scoped and will be automatically released when: - Close() is called explicitly - The connection is closed - The process terminates
db is taken as a common5.WriteDB rather than a *sql.DB so that a backend may decorate its write path; only Conn is used here, and the connection it returns is held for the lock's lifetime.
func (*AdvisoryLock) Close ¶
func (l *AdvisoryLock) Close() error
Close releases the advisory lock and closes the connection. It is safe to call Close multiple times.
type AuditTransactionStore ¶
type AuditTransactionStore struct {
*sqlcommon.TransactionStore
// contains filtered or unexported fields
}
AuditTransactionStore wraps common.TransactionStore to add advisory lock to schema creation
func NewAuditTransactionStore ¶
func NewAuditTransactionStore(dbs *scommon.RWDB, tableNames sqlcommon.TableNames) (*AuditTransactionStore, error)
NewAuditTransactionStore creates a new AuditTransactionStore.
func (*AuditTransactionStore) AcquireLeadership ¶ added in v0.24.0
func (s *AuditTransactionStore) AcquireLeadership(ctx context.Context, lockID int64) (tokensdriver.RecoveryLeadership, bool, error)
AcquireLeadership overrides the base no-op to take a real PostgreSQL advisory lock for lockID, independent of the recovery lock bound at construction.
func (*AuditTransactionStore) ClaimPendingTransactions ¶ added in v0.21.0
func (s *AuditTransactionStore) ClaimPendingTransactions(ctx context.Context, params tokensdriver.RecoveryClaimParams) ([]*tokensdriver.RecoveryClaim, error)
ClaimPendingTransactions atomically claims a batch of pending audit transactions.
Without this override the store inherits the permissive SELECT from sqlcommon.TransactionStore, which persists no claim at all: every replica selects the same pending rows on every sweep and processes all of them. The owner path has had the atomic claim since it was introduced; audit was simply never given it.
func (*AuditTransactionStore) CreateSchema ¶
func (s *AuditTransactionStore) CreateSchema() error
CreateSchema overrides the base CreateSchema to ensure GetSchema is called on the correct receiver
func (*AuditTransactionStore) GetSchema ¶
func (s *AuditTransactionStore) GetSchema() string
GetSchema overrides the base GetSchema to prefix with advisory lock
func (*AuditTransactionStore) ReleaseRecoveryClaim ¶ added in v0.21.0
func (s *AuditTransactionStore) ReleaseRecoveryClaim(ctx context.Context, txID string, owner string, _ string) error
ReleaseRecoveryClaim releases the recovery claim on an audit transaction. The inherited implementation is a no-op, which would leave the claim set until its lease expired even after the sweep finished with the row.
Deliberately drops the caller's message instead of forwarding it to status_message. recoverTransaction (recovery/manager.go) always releases with a claim-bookkeeping message ("recovered successfully", "recovery failed: %v"), not the tx's actual audit-trail reason: applyFinalityLogic (ttx/finality/recovery.go) already writes that reason via SetStatus *before* this release runs whenever a row's status genuinely changes, and returns nil without touching status for a still-Pending tx (Busy/Unknown), a case recoverTransaction cannot tell apart from success. Forwarding message here would overwrite a real ledger rejection reason with "recovered successfully", and would do so on every still-pending row on every sweep, exactly what an audit trail must not do. The owner path keeps forwarding the bookkeeping message; that behavior predates this PR and is unchanged here.
func (*AuditTransactionStore) WriteDB ¶
func (s *AuditTransactionStore) WriteDB() *sql.DB
WriteDB returns the underlying write *sql.DB. Used by the auditor distributed locker to share the connection pool.
type Driver ¶
type Driver struct {
// Lazy providers for various store types to ensure they are initialized only when needed.
TokenLock lazy.Provider[fscPostgres.Config, *TokenLockStore]
Wallet lazy.Provider[fscPostgres.Config, *WalletStore]
Identity lazy.Provider[fscPostgres.Config, *IdentityStore]
Token lazy.Provider[fscPostgres.Config, *TokenStore]
AuditTx lazy.Provider[fscPostgres.Config, *AuditTransactionStore]
OwnerTx lazy.Provider[fscPostgres.Config, *TransactionStore]
Endorser lazy.Provider[fscPostgres.Config, *EndorserStore]
KeyStore lazy.Provider[fscPostgres.Config, *KeystoreStore]
// contains filtered or unexported fields
}
Driver implements the token storage driver for Postgres.
func NewDriverWithDbProvider ¶
func NewDriverWithDbProvider(config driver3.Config, dbProvider fscPostgres.DbProvider) *Driver
NewDriverWithDbProvider returns a new Driver for Postgres using the given database provider.
func (*Driver) NewAuditTransaction ¶
func (d *Driver) NewAuditTransaction(name driver2.PersistenceName, params ...string) (driver3.AuditTransactionStore, error)
NewAuditTransaction returns a new AuditTransactionStore.
func (*Driver) NewEndorser ¶
func (d *Driver) NewEndorser(name driver2.PersistenceName, params ...string) (driver3.EndorserStore, error)
NewEndorser returns a new EndorserStore.
func (*Driver) NewIdentity ¶
func (d *Driver) NewIdentity(name driver2.PersistenceName, params ...string) (driver3.IdentityStore, error)
NewIdentity returns a new IdentityStore.
func (*Driver) NewKeyStore ¶
func (d *Driver) NewKeyStore(name driver2.PersistenceName, params ...string) (driver3.KeyStore, error)
NewKeyStore returns a new KeyStoreStore.
func (*Driver) NewOwnerTransaction ¶
func (d *Driver) NewOwnerTransaction(name driver2.PersistenceName, params ...string) (driver3.TokenTransactionStore, error)
NewOwnerTransaction returns a new TokenTransactionStore.
func (*Driver) NewToken ¶
func (d *Driver) NewToken(name driver2.PersistenceName, params ...string) (driver3.TokenStore, error)
NewToken returns a new TokenStore.
func (*Driver) NewTokenLock ¶
func (d *Driver) NewTokenLock(name driver2.PersistenceName, params ...string) (driver3.TokenLockStore, error)
NewTokenLock returns a new TokenLockStore.
func (*Driver) NewWallet ¶
func (d *Driver) NewWallet(name driver2.PersistenceName, params ...string) (driver3.WalletStore, error)
NewWallet returns a new WalletStore.
type EndorserStore ¶
type EndorserStore struct {
*common3.EndorserStore
// contains filtered or unexported fields
}
EndorserStore wraps common.EndorserStore to add advisory lock to schema creation
func NewEndorserStore ¶
func NewEndorserStore(dbs *scommon.RWDB, tables common3.TableNames) (*EndorserStore, error)
NewEndorserStore creates a new EndorserStore for Postgres
func (*EndorserStore) CreateSchema ¶
func (s *EndorserStore) CreateSchema() error
CreateSchema overrides the base CreateSchema to ensure GetSchema is called on the correct receiver
func (*EndorserStore) GetSchema ¶
func (s *EndorserStore) GetSchema() string
GetSchema overrides the base GetSchema to prefix with advisory lock
type IdentityNotifier ¶
type IdentityNotifier struct {
*Notifier
}
IdentityNotifier handles notifications for identity configurations.
func NewIdentityNotifier ¶
func NewIdentityNotifier(dbs *scommon.RWDB, tableNames sqlcommon.TableNames, dataSource string) (*IdentityNotifier, error)
NewIdentityNotifier returns a new IdentityNotifier for the given RWDB and table names.
func (*IdentityNotifier) Subscribe ¶
func (n *IdentityNotifier) Subscribe(callback func(idriver.Operation, idriver.IdentityConfigurationRecord)) error
Subscribe registers a callback function to be called when an identity configuration is inserted or updated.
type IdentityStore ¶
type IdentityStore struct {
*sqlcommon.IdentityStore
// contains filtered or unexported fields
}
IdentityStore wraps common.IdentityStore to add advisory lock to schema creation
func NewIdentityStore ¶
func NewIdentityStore(dbs *scommon.RWDB, tableNames sqlcommon.TableNames, dataSource string) (*IdentityStore, error)
NewIdentityStore creates a new IdentityStore with advisory lock support
func (*IdentityStore) CreateSchema ¶
func (s *IdentityStore) CreateSchema() error
CreateSchema overrides the base CreateSchema to ensure GetSchema is called on the correct receiver
func (*IdentityStore) GetSchema ¶
func (s *IdentityStore) GetSchema() string
GetSchema overrides the base GetSchema to prefix with advisory lock
type KeystoreStore ¶
type KeystoreStore struct {
*common3.KeystoreStore
// contains filtered or unexported fields
}
KeystoreStore wraps common.KeystoreStore to add advisory lock to schema creation
func NewKeystoreStore ¶
func NewKeystoreStore(dbs *common2.RWDB, tableNames common3.TableNames) (*KeystoreStore, error)
NewKeystoreStore returns a new KeystoreStore for the given RWDB and table names.
func (*KeystoreStore) CreateSchema ¶
func (s *KeystoreStore) CreateSchema() error
CreateSchema overrides the base CreateSchema to ensure GetSchema is called on the correct receiver
func (*KeystoreStore) GetSchema ¶
func (s *KeystoreStore) GetSchema() string
GetSchema overrides the base GetSchema to prefix with advisory lock
type Notifier ¶
type Notifier struct {
// contains filtered or unexported fields
}
Notifier implements a simple subscription API to listen for updates on a database table.
Delivery is serialised per table: one goroutine owns the LISTEN connection, reads notifications one at a time and invokes every subscriber inline (see dispatch). A subscriber that blocks therefore stalls delivery of every later notification on this table's channel, for every subscriber. Callbacks must be fast and non-blocking - hand slow work to a goroutine or a queue. See Subscribe for the full contract.
Notifications are also not a durable log. Postgres queues them only for sessions that are already LISTENing and never replays them, so anything emitted before the listener registers, or while a dropped connection is being re-established, is lost. Subscribe closes the first window by waiting for LISTEN; TransportError reports the second. A subscriber that needs to be correct rather than merely prompt must therefore treat a notification as a hint to re-read the table, not as the record of what changed.
func NewNotifier ¶
func NewNotifier( writeDB *sql.DB, table, dataSource string, notifyOperations []driver.Operation, primaryKeys ...PrimaryKey, ) *Notifier
NewNotifier returns a new Notifier for the given RWDB and table names.
func (*Notifier) CreateSchema ¶
CreateSchema creates the notification objects in the database. It returns an error if the schema creation fails.
func (*Notifier) GetSchema ¶
GetSchema returns the SQL schema for creating the notification objects in the database.
func (*Notifier) ListenerError ¶
ListenerError returns a channel that receives errors from the listener. The caller should consume this channel to detect listener failures.
func (*Notifier) Subscribe ¶
func (db *Notifier) Subscribe(callback driver.TriggerCallback) error
Subscribe registers a callback function to be called when a matching database event occurs. It returns an error if the notifier is closed or if the listener fails to start.
The callback is invoked synchronously on the single listener goroutine that owns this table's LISTEN connection, so it must not block: while it runs, no other notification on the channel is delivered, to this or any other subscriber. It must not call back into the notifier either (Subscribe, Close and UnsubscribeAll all take the same lock the dispatch loop reads under). Anything slow - a query, an RPC, a lock - belongs on a goroutine or a queue the callback only hands work to.
The first Subscribe installs the notification trigger and then waits, up to listenReadyTimeout, for the listener to register LISTEN. When that wait succeeds, a row written after Subscribe returns is guaranteed to reach the callback; previously the call returned after a fixed 100ms that had nothing to do with whether the channel was live, so a write racing startup was silently dropped.
A nil return does not by itself carry that guarantee. If the wait times out, the timeout is logged and Subscribe still returns nil - the listener keeps retrying, and failing the subscription would be worse than a late one - so a row written while LISTEN is still unregistered is dropped by Postgres, which queues notifications only for sessions already listening. Rows written between the trigger's installation and the point where the listener is ready - by another process, or by this one before Subscribe returns - are not replayed.
func (*Notifier) TransportError ¶ added in v0.18.0
TransportError returns a channel that receives non-fatal transport errors reported by the underlying listener (e.g. a dropped LISTEN connection that is being reconnected). The notifier keeps running across such errors; the channel merely lets a consumer learn that notifications may have been missed during the outage. Sends are best-effort and buffered depth 1, so only the most recent error is retained when the channel is not being drained.
func (*Notifier) UnsubscribeAll ¶
UnsubscribeAll removes all subscribers.
type PrimaryKey ¶
type PrimaryKey struct {
// contains filtered or unexported fields
}
PrimaryKey represents a primary key column with its value decoder
func NewSimplePrimaryKey ¶
func NewSimplePrimaryKey(name driver.ColumnKey) *PrimaryKey
type TokenLockStore ¶
type TokenLockStore struct {
*common5.TokenLockStore
// contains filtered or unexported fields
}
TokenLockStore implements the token lock storage for Postgres.
func NewTokenLockStore ¶
func NewTokenLockStore(dbs *common2.RWDB, tableNames common5.TableNames) (*TokenLockStore, error)
NewTokenLockStore returns a new TokenLockStore for the given RWDB and table names, using the default (insert) lock strategy.
func (*TokenLockStore) AcquireCleanupLeadership ¶ added in v0.17.0
func (db *TokenLockStore) AcquireCleanupLeadership(ctx context.Context) (driver.CleanupLeadership, bool, error)
AcquireCleanupLeadership attempts to acquire a Postgres advisory lock so only one replica runs Cleanup per tick for this TMS; others skip the tick and release no held resources, so contention is limited to the acquire attempt itself. The lock id and factory are fixed at construction. Note the winner holds a dedicated connection off writeDB for the tick's duration (see NewAdvisoryLock). This lock, the recovery lock and the keystore-cleanup lock are all now derived per TMS rather than shared node-wide, and FSC keys connection pools by data source alone, so TMSes sharing one database share one *sql.DB. A node running N such TMSes can therefore have up to 3N connections pinned by lock holders at once, before counting the further connections winners need for their own work (e.g. recovery's ClaimPendingTransactions). Size writeDB's maxOpenConns against that floor, not a single spare connection. See #1798.
func (*TokenLockStore) Cleanup ¶
Cleanup removes stale token locks that have expired. The deletion itself is the backend-independent one implemented by the embedded store; Postgres only adds the logging of the rows that are about to go.
func (*TokenLockStore) CreateSchema ¶
func (s *TokenLockStore) CreateSchema() error
CreateSchema overrides the base CreateSchema to ensure GetSchema is called on the correct receiver
func (*TokenLockStore) GetSchema ¶
func (s *TokenLockStore) GetSchema() string
GetSchema overrides the base GetSchema to prefix with advisory lock
func (*TokenLockStore) Lock ¶ added in v0.26.0
func (db *TokenLockStore) Lock(ctx context.Context, tokenID *token.ID, consumerTxID transaction.ID, walletID string) error
Lock locks the token for consumerTxID, using the configured strategy. The default (LockStrategyInsert) delegates unchanged to the embedded store: an INSERT that surfaces a lost race as a unique-constraint violation. LockStrategyOnConflict and LockStrategySkipLocked both use INSERT ... ON CONFLICT DO NOTHING RETURNING instead: a lost race is a normal zero-row result, not a server-side error. Note this overrides Lock, not LockAt: the embedded TokenLockStore.Lock calls LockAt on itself, not on this type (Go has no virtual dispatch), so overriding LockAt here would never be reached from callers that go through Lock.
func (*TokenLockStore) LockBatch ¶ added in v0.26.0
func (db *TokenLockStore) LockBatch(ctx context.Context, tokenIDs []*token.ID, consumerTxID transaction.ID, _ string) (driver.BatchLockOutcome, error)
LockBatch attempts to lock, in a single round trip, every token in tokenIDs on behalf of consumerTxID, and reports per candidate how the claim resolved: the tokens it won, and those it refused because they are no longer spendable (driver.BatchLockOutcome). It never claims a token outside tokenIDs, so callers remain responsible for supplying only candidates that are already known to be spendable: LockBatch itself applies no eligibility predicate beyond "not already locked". At most MaxLockBatchCandidates may be claimed per call, since the claim is one statement and the wire protocol bounds how many parameters one carries; a longer batch is refused outright, with nothing locked. Under LockStrategySkipLocked the claim uses FOR UPDATE SKIP LOCKED on the underlying Tokens rows, so a caller walks past rows a concurrent claimant is already processing instead of colliding with them; under LockStrategyOnConflict and LockStrategyInsert it issues the same multi-row INSERT ... ON CONFLICT DO NOTHING as tryInsertOnConflict's single-token callers, for the whole window in one round trip - only the plain LockStrategyInsert single-token Lock path (which must surface a lost race as a unique-constraint violation, not a zero-row result) does not go through this.
func (*TokenLockStore) RoundTrips ¶ added in v0.26.0
func (db *TokenLockStore) RoundTrips() int64
RoundTrips returns the number of Lock and LockBatch calls issued against this store instance since construction. Instrumentation only, for benchmarking Phase 6's lock strategies; not part of the driver.TokenLockStore contract.
func (*TokenLockStore) UniqueViolations ¶ added in v0.26.0
func (db *TokenLockStore) UniqueViolations() int64
UniqueViolations returns the number of Lock calls that observed a real server-side unique-constraint violation, as opposed to a clean zero-row result - only possible under LockStrategyInsert. Instrumentation only, for benchmarking Phase 6's lock strategies; not part of the driver.TokenLockStore contract.
type TokenNotifier ¶
type TokenNotifier struct {
*Notifier
}
TokenNotifier handles notifications for tokens.
func NewTokenNotifier ¶
func NewTokenNotifier(dbs *scommon.RWDB, tableNames sqlcommon.TableNames, dataSource string) (*TokenNotifier, error)
NewTokenNotifier returns a new TokenNotifier for the given RWDB and table names.
func (*TokenNotifier) Subscribe ¶
func (n *TokenNotifier) Subscribe(callback func(tokensdriver.Operation, tokensdriver.TokenRecordReference)) error
Subscribe registers a callback function to be called when a token is inserted, updated, or deleted.
type TokenStore ¶
type TokenStore struct {
*sqlcommon.TokenStore
// contains filtered or unexported fields
}
TokenStore wraps common.TokenStore to add advisory lock to schema creation
func NewTokenStoreWithNotifier ¶
func NewTokenStoreWithNotifier(dbs *scommon.RWDB, tableNames sqlcommon.TableNames, notifier *TokenNotifier) (*TokenStore, error)
func (*TokenStore) CreateSchema ¶
func (s *TokenStore) CreateSchema() error
CreateSchema overrides the base CreateSchema to ensure GetSchema is called on the correct receiver
func (*TokenStore) GetSchema ¶
func (s *TokenStore) GetSchema() string
GetSchema overrides the base GetSchema to prefix with the advisory locks covering every table the schema creates: this store's own, and the TokenLocks table it also emits.
type TransactionNotifier ¶
type TransactionNotifier struct {
*Notifier
}
TransactionNotifier handles notifications for transaction status changes.
func NewTransactionNotifier ¶
func NewTransactionNotifier(dbs *scommon.RWDB, tableNames sqlcommon.TableNames, dataSource string) (*TransactionNotifier, error)
NewTransactionNotifier returns a new TransactionNotifier for the given RWDB and table names.
func (*TransactionNotifier) Subscribe ¶
func (n *TransactionNotifier) Subscribe(callback func(tokensdriver.Operation, tokensdriver.TransactionRecordReference)) error
Subscribe registers a callback function to be called when a transaction request status is updated.
type TransactionStore ¶
type TransactionStore struct {
*sqlcommon.TransactionStore
// contains filtered or unexported fields
}
TransactionStore extends the common TransactionStore with PostgreSQL-specific atomic claim operations.
func NewTransactionStoreWithNotifier ¶
func NewTransactionStoreWithNotifier(dbs *scommon.RWDB, tableNames sqlcommon.TableNames, notifier *TransactionNotifier) (*TransactionStore, error)
NewTransactionStoreWithNotifier creates a new TransactionStore with the provided notifier and recovery support.
func (*TransactionStore) AcquireLeadership ¶ added in v0.24.0
func (s *TransactionStore) AcquireLeadership(ctx context.Context, lockID int64) (tokensdriver.RecoveryLeadership, bool, error)
AcquireLeadership overrides the base no-op to take a real PostgreSQL advisory lock for lockID, independent of the recovery lock bound at construction.
func (*TransactionStore) ClaimPendingTransactions ¶
func (db *TransactionStore) ClaimPendingTransactions(ctx context.Context, params tokensdriver.RecoveryClaimParams) ([]*tokensdriver.RecoveryClaim, error)
ClaimPendingTransactions atomically claims a batch of pending transactions.
func (*TransactionStore) CleanupExpiredClaims ¶
func (db *TransactionStore) CleanupExpiredClaims(ctx context.Context) (int, error)
CleanupExpiredClaims removes expired recovery claims. Returns the number of claims cleaned up.
func (*TransactionStore) CreateSchema ¶
func (s *TransactionStore) CreateSchema() error
CreateSchema overrides the base CreateSchema to ensure GetSchema is called on the correct receiver
func (*TransactionStore) GetSchema ¶
func (s *TransactionStore) GetSchema() string
GetSchema overrides the base GetSchema to prefix with advisory lock
func (*TransactionStore) ReleaseRecoveryClaim ¶
func (db *TransactionStore) ReleaseRecoveryClaim(ctx context.Context, txID string, owner string, message string) error
ReleaseRecoveryClaim releases the recovery claim on a transaction.
type WalletStore ¶
type WalletStore struct {
*common3.WalletStore
// contains filtered or unexported fields
}
WalletStore wraps common.WalletStore to add advisory lock to schema creation
func NewWalletStore ¶
func NewWalletStore(dbs *common2.RWDB, tableNames common3.TableNames) (*WalletStore, error)
NewWalletStore returns a new WalletStore for the given RWDB and table names.
func (*WalletStore) CreateSchema ¶
func (s *WalletStore) CreateSchema() error
CreateSchema overrides the base CreateSchema to ensure GetSchema is called on the correct receiver
func (*WalletStore) GetSchema ¶
func (s *WalletStore) GetSchema() string
GetSchema overrides the base GetSchema to prefix with advisory lock