client

package
v0.0.0-...-29d77a8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 6, 2026 License: Apache-2.0 Imports: 31 Imported by: 0

Documentation

Overview

Package client implements the FDB client transaction lifecycle. This is the Go equivalent of NativeAPI.actor.cpp.

Index

Constants

View Source
const (
	ErrNotCommitted              = 1020 // not_committed (conflict)
	ErrCommitUnknownResult       = 1021 // commit_unknown_result
	ErrTransactionTooOld         = 1007 // transaction_too_old
	ErrFutureVersion             = 1009 // future_version
	ErrWrongShardServer          = 1001 // wrong_shard_server (1062 is change_feed_cancelled — do not confuse)
	ErrTransactionTimedOut       = 1031 // transaction_timed_out (NEVER retryable)
	ErrAccessedUnreadable        = 1036 // accessed_unreadable — read of a pending versionstamped key (NOT retryable; RFC-098)
	ErrProcessBehind             = 1037 // process_behind
	ErrWatchCancelled            = 1029 // watch_cancelled — SS watch limit exceeded; client polls instead
	ErrTooManyWatches            = 1032 // too_many_watches — outstanding-watch cap exceeded (client-side)
	ErrTimedOut                  = 1004 // timed_out — the SS occasionally times out a watch; re-arm
	ErrDatabaseLocked            = 1038 // database_locked
	ErrClusterVersionChanged     = 1039 // cluster_version_changed (MAYBE_COMMITTED)
	ErrProxyMemoryLimitExceeded  = 1042 // commit_proxy_memory_limit_exceeded
	ErrBatchTransactionThrottled = 1051 // batch_transaction_throttled
	ErrGrvProxyMemoryLimit       = 1078 // grv_proxy_memory_limit_exceeded
	ErrBlobGranuleRequestFailed  = 1079 // blob_granule_request_failed (retryable, C++ NativeAPI.actor.cpp)
	ErrTagThrottled              = 1213 // tag_throttled
	ErrProxyTagThrottled         = 1223 // proxy_tag_throttled
	ErrThrottledHotShard         = 1235 // transaction_throttled_hot_shard (FDB 7.4+, future-proof)
	ErrRangeLocked               = 1242 // transaction_rejected_range_locked (FDB 7.4+, future-proof)
	ErrOperationFailed           = 4    // operation_failed (endpoint not supported)
	ErrAllAlternativesFailed     = 1006 // all_alternatives_failed (Layer 2 only)
	ErrAllProxiesUnreachable     = 1200 // Go-internal: all proxies failed at Layer 2 (NOT C++ 1200=recruitment_failed)
	ErrInvertedRange             = 2005 // inverted_range (begin > end)
	ErrRangeLimitsInvalid        = 2012 // range_limits_invalid (e.g. a row limit < -1)
	ErrInvalidMutationType       = 2018 // invalid_mutation_type (a non-atomic op passed to Atomic())
)

FDB error codes. Source of truth: flow/error_definitions.h + fdb_c.cpp fdb_error_predicate().

View Source
const (
	NoTenantID           int64 = -1
	UnlimitedBytes       int32 = 0x7FFFFFFF
	DefaultRPCTimeout          = 5 * time.Second
	CoordinatorTimeout         = 30 * time.Second // OpenDatabaseCoordRequest + GRV batch context
	BootstrapMaxBackoff        = 5 * time.Second  // bootstrap retry backoff cap
	MaxWrongShardRetries       = 50               // C++ is unbounded (relies on tx 5s timeout); 50×10ms = 500ms, generous safety margin
)

Client constants. These mirror CLIENT_KNOBS in NativeAPI.actor.cpp.

View Source
const (
	LatestVersion  int64 = -2 // C++ latestVersion — used in GetKeyServerLocationsRequest.MinTenantVersion
	InvalidVersion int64 = -1 // C++ invalidVersion — used in GetReadVersionRequest.MaxVersion
)

C++ version constants from flow/flow.h.

View Source
const (
	EndpointGetValue              = 0  // StorageServerInterface::getValue
	EndpointGetKey                = 1  // StorageServerInterface::getKey
	EndpointGetKeyValues          = 2  // StorageServerInterface::getKeyValues
	EndpointGetShardState         = 3  // StorageServerInterface::getShardState
	EndpointWaitMetrics           = 4  // StorageServerInterface::waitMetrics
	EndpointSplitMetrics          = 5  // StorageServerInterface::splitMetrics
	EndpointGetStorageMetrics     = 6  // StorageServerInterface::getStorageMetrics
	EndpointWaitFailure           = 7  // StorageServerInterface::waitFailure
	EndpointGetQueuingMetrics     = 8  // StorageServerInterface::getQueuingMetrics
	EndpointGetKeyValueStoreType  = 9  // StorageServerInterface::getKeyValueStoreType
	EndpointWatchValue            = 10 // StorageServerInterface::watchValue
	EndpointGetReadHotRanges      = 11 // StorageServerInterface::getReadHotRanges
	EndpointGetRangeSplitPoints   = 12 // StorageServerInterface::getRangeSplitPoints
	EndpointGetKeyValuesStream    = 13 // StorageServerInterface::getKeyValuesStream
	EndpointGetKeyServerLocations = 2  // CommitProxyInterface::getKeyServerLocations
)

Endpoint indices from C++ interface definitions. Indices are relative to each interface's base token via getAdjustedEndpoint().

StorageServerInterface (StorageServerInterface.h):

getValue=0, getKey=1, getKeyValues=2, getShardState=3, waitMetrics=4,
splitMetrics=5, getStorageMetrics=6, waitFailure=7, getQueuingMetrics=8,
getKeyValueStoreType=9, watchValue=10, getReadHotRanges=11,
getRangeSplitPoints=12, getKeyValuesStream=13

CommitProxyInterface (CommitProxyInterface.h):

commit=0, ..., getKeyServerLocations=2

Variables

View Source
var ErrNeedFullRYW = errors.New("need full RYW path")

ErrNeedFullRYW is returned by GetPipelined when the key has pending atomics that require a server read + merge through the full ryw.get() path.

Functions

func ReadEndpointFromSlot

func ReadEndpointFromSlot(r *wire.Reader, slot int) (types.Endpoint, error)

ReadEndpointFromSlot reads an Endpoint from a proxy/storage interface at the given slot. Chain: Interface[slot] → RequestStream wrapper (1 field RelOff) → Endpoint inner.

Types

type ClientMetrics

type ClientMetrics struct {
	// contains filtered or unexported fields
}

ClientMetrics holds the per-Database transaction counters — the operational subset of C++ DatabaseContext's CounterCollection (DatabaseContext.h:585-635), with the C++ names and the C++ increment sites (RFC-097):

  • commit started/completed: commitMutations entry (NativeAPI.actor.cpp:6808; the empty/read-only fast path at :6800-6806 does NOT count) / tryCommit success (:6673). Started−Completed = failed or in-flight (intentional asymmetry, matching C++).
  • the per-error-code retry counters: Transaction::onError's arms (:7749-:7772).
  • read versions completed (+ per priority): extractReadVersion (:7428-7440) — i.e. per transaction served by a REAL GRV reply; cache hits do not count there in C++ and do not count here.

transactionRetries is a Go-only aggregate (total OnError-sanctioned retries); C++ tracks retries per-transaction only (trState->numErrors). It also counts codes C++ retries WITHOUT a counter (database_locked 1038, blob_granule_request_failed 1079 — :7743-7747, plus the Go-internal 1200 and future-proof 1235/1242).

Counters are monotonic; consumers poll Database.Metrics() and diff. There is no periodic trace emission (C++ logs TransactionMetrics on a timer; the Go analog is the consumer's scrape interval) — the only gap is no persisted history if nothing polls before process death.

func (*ClientMetrics) Snapshot

func (m *ClientMetrics) Snapshot() ClientMetricsSnapshot

Snapshot returns a point-in-time copy of all counters.

type ClientMetricsSnapshot

type ClientMetricsSnapshot struct {
	TransactionsCommitStarted   int64
	TransactionsCommitCompleted int64

	TransactionsNotCommitted        int64
	TransactionsMaybeCommitted      int64
	TransactionsResourceConstrained int64
	TransactionsProcessBehind       int64
	TransactionsThrottled           int64
	TransactionsTooOld              int64
	TransactionsFutureVersions      int64

	TransactionReadVersionsCompleted          int64
	TransactionBatchReadVersionsCompleted     int64
	TransactionDefaultReadVersionsCompleted   int64
	TransactionImmediateReadVersionsCompleted int64
	GRVCacheHits                              int64 // RFC-104: served from the GRV cache (opt-in)

	TransactionRetries int64

	RecoveredPanics               int64 // RFC-110: panics recovered by the goroutine backstop
	RecoveredPanicsConsecutiveMax int64 // RFC-110: high-water of any loop's consecutive-panic streak

	ClientConnectionFailures int64 // RFC-114: connection/dial failures (Go-only observability)
	CoordinatorChanges       int64 // RFC-114: followed coordinator forwards (Go-only observability)

	// Latency distributions (RFC-114), seconds. Instantaneous reads, not monotonic.
	ReadLatency        LatencyStats // GetValue round-trip
	CommitLatency      LatencyStats // commit round-trip
	GRVLatency         LatencyStats // GRV round-trip
	TransactionLatency LatencyStats // total transaction latency (C++ "latencies")
}

ClientMetricsSnapshot is a point-in-time copy of the counters. Fields are monotonic; diff two snapshots for rates.

type ClusterFile

type ClusterFile struct {
	Description  string
	ID           string
	Coordinators []string // "host:port" addresses for TCP connection (":tls" suffix stripped)
	// UseTLS is true when the coordinators carry the ":tls" suffix (FDB
	// FLAG_TLS). A real cluster is uniformly TLS, so this is a single flag;
	// mixed TLS/non-TLS coordinators are rejected at parse time.
	UseTLS bool
}

ClusterFile represents an fdb.cluster file. Format: "<description>:<id>@<host>:<port>[,<host>:<port>...]"

func ParseClusterFile

func ParseClusterFile(path string) (*ClusterFile, error)

ParseClusterFile reads and parses an fdb.cluster file.

func ParseClusterString

func ParseClusterString(s string) (*ClusterFile, error)

ParseClusterString parses a cluster connection string.

func (*ClusterFile) String

func (cf *ClusterFile) String() string

String renders the connection string in C++ ClusterConnectionString::toString byte-order (MonitorLeader.actor.cpp:438-453): `description:id@`, then all IP coordinators in original order, then all hostname coordinators in original order, comma-joined, each with ":tls" re-appended when UseTLS. This is the cross-tool-shared on-disk form; it must be byte-identical to what a C++/Java client would write so they can read the file back. Equality between two ClusterFiles is defined as a.String() == b.String() (matches C++ upToDate's toString() compare) — the serialization is the single source of truth.

type DBInfo

type DBInfo struct {
	ID            transport.UID
	GRVProxies    []ProxyInfo
	CommitProxies []ProxyInfo
	ClusterID     transport.UID
	// Forward, when non-empty, is the serialized new ClusterConnectionString the
	// coordinators handed back instead of proxies — the C++ ClientDBInfo.forward
	// field (CommitProxyInterface.h:132). Set during a `coordinators auto`/`change`
	// rotation; the proxies on a forward reply are ignored (RFC-111 Path A).
	Forward string
}

DBInfo holds the current cluster topology. Received from coordinators via OpenDatabaseCoordRequest.

type Database

type Database struct {
	// contains filtered or unexported fields
}

Database is the public API entry point. C++: Database is a Reference<DatabaseContext> — a handle, not state.

Safe for concurrent use by multiple goroutines.

func OpenDatabase

func OpenDatabase(ctx context.Context, clusterFilePath string, opts ...Option) (*Database, error)

OpenDatabase opens a database connection using a cluster file. The provided ctx is used for the initial bootstrap (coordinator connection). Background goroutines use an internal context cancelled by Close().

func OpenDatabaseFromConfig

func OpenDatabaseFromConfig(ctx context.Context, cf *ClusterFile, opts ...Option) (*Database, error)

OpenDatabaseFromConfig creates and bootstraps a Database from a ClusterFile. See WithDialFunc / WithTLSConfig for options.

func (*Database) Close

func (d *Database) Close() error

func (*Database) CreateTransaction

func (d *Database) CreateTransaction() *Transaction

CreateTransaction creates a new transaction. Database-level defaults (timeout, retry limit, system key access) are applied.

func (*Database) GetDBInfo

func (d *Database) GetDBInfo() *DBInfo

GetDBInfo returns the current cluster topology (proxy lists, cluster ID). Returns nil if not yet connected.

func (*Database) HedgeEnabled

func (d *Database) HedgeEnabled() bool

HedgeEnabled returns whether speculative second requests are active.

func (*Database) InvalidateGRVCache

func (d *Database) InvalidateGRVCache()

InvalidateGRVCache resets the GRV cache so the next transaction fetches a fresh read version from the GRV proxy. Use after external writes.

func (*Database) Metrics

func (d *Database) Metrics() ClientMetricsSnapshot

Metrics returns a point-in-time snapshot of this handle's operational counters (RFC-097) — the C++ DatabaseContext TransactionMetrics subset. Counters are monotonic; poll and diff for rates. This is the export hook: Prometheus/OTel consumers are pull-based readers of exactly this shape (see pkg/fdbgo/fdbmetrics for a ready-made scrape handler).

func (*Database) ReadTransact

func (d *Database) ReadTransact(ctx context.Context, fn func(tx *Transaction) (any, error)) (any, error)

ReadTransact runs a read-only function in a transaction with automatic retry. The transaction is never committed — only reads are performed.

func (*Database) SetDefaultAccessSystemKeys

func (d *Database) SetDefaultAccessSystemKeys()

SetDefaultAccessSystemKeys makes all new transactions automatically call SetAccessSystemKeys(), allowing reads AND writes of \xff-prefixed system keys.

func (*Database) SetDefaultReadSystemKeys

func (d *Database) SetDefaultReadSystemKeys()

SetDefaultReadSystemKeys makes all new transactions automatically call SetReadSystemKeys(), allowing reads of \xff-prefixed system keys.

func (*Database) SetDialFunc

func (d *Database) SetDialFunc(fn transport.DialFunc)

SetDialFunc sets a custom dialer for all new connections. Must be called before OpenDatabase or any transactions.

func (*Database) SetHedgeEnabled

func (d *Database) SetHedgeEnabled(enabled bool)

SetHedgeEnabled controls speculative second requests (hedge) for read RPCs. When enabled (default), slow reads are rescued by sending a backup request to a second server after max(10ms, 2×latency). Disable for debugging or benchmarking the non-hedged path.

func (*Database) SetMaxWatches

func (d *Database) SetMaxWatches(n int64) error

SetMaxWatches sets the cap on concurrently-outstanding watches for this Database (FDB_DB_OPTION_MAX_WATCHES). Once the count would exceed it, a new watch fails with too_many_watches (1032). Matches C++ DatabaseContext maxOutstandingWatches; default 10000. 0 is a REAL cap (no watches allowed — the first fails), NOT "unlimited". An out-of-range value (< 0 or > ABSOLUTE_MAX_WATCHES) is REJECTED with invalid_option_value (2006) and the cap is left UNCHANGED — C++ extractIntOption(value, 0, ABSOLUTE_MAX_WATCHES) throws on out-of-range, it does NOT clamp (NativeAPI.actor.cpp:2092-2102 / :2139).

func (*Database) SetTransactionMaxRetryDelay

func (d *Database) SetTransactionMaxRetryDelay(ms int64)

SetTransactionMaxRetryDelay sets the default max retry delay (ms) for all transactions. Matches FDB_DB_OPTION_TRANSACTION_MAX_RETRY_DELAY.

func (*Database) SetTransactionRetryLimit

func (d *Database) SetTransactionRetryLimit(retries int64)

SetTransactionRetryLimit sets the default retry limit for all transactions. Matches FDB_DB_OPTION_TRANSACTION_RETRY_LIMIT.

func (*Database) SetTransactionSizeLimit

func (d *Database) SetTransactionSizeLimit(limit int64)

SetTransactionSizeLimit sets the default size limit for all transactions. Matches FDB_DB_OPTION_TRANSACTION_SIZE_LIMIT.

func (*Database) SetTransactionTimeout

func (d *Database) SetTransactionTimeout(ms int64)

SetTransactionTimeout sets the default timeout (in milliseconds) for all transactions created from this database. Matches FDB_DB_OPTION_TRANSACTION_TIMEOUT.

func (*Database) Transact

func (d *Database) Transact(ctx context.Context, fn func(tx *Transaction) (any, error)) (any, error)

Transact runs a function in a transaction with automatic retry. This is the primary API for interacting with FDB. The transaction is reused across retries — retryCount and backoff escalate.

type DialFunc

type DialFunc = transport.DialFunc

DialFunc is the custom-dialer signature (alias of transport.DialFunc) so callers configuring WithDialFunc don't need to import the transport package.

type KeyRange

type KeyRange struct {
	Begin []byte
	End   []byte
}

KeyRange represents a range [Begin, End).

type KeyValue

type KeyValue = types.KeyValueRef

KeyValue is a key-value pair returned from reads.

type LatencyStats

type LatencyStats struct {
	Count  int64
	Sum    float64 // seconds — the summary _sum (and Mean = Sum/Count)
	Mean   float64
	Median float64 // p50
	P90    float64
	P99    float64
	Min    float64 // exact (C++ DDSketchBase::min)
	Max    float64 // exact (C++ DDSketchBase::max)
}

LatencyStats is a point-in-time summary of one latency distribution (RFC-114), in SECONDS. Unlike the monotonic counters, these are instantaneous distribution reads — diffing two snapshots is not meaningful. Median/P90/P99 are DDSketch quantiles (±0.5% relative error). C++ emits p90/p98 only for the aggregate transaction latency; Go exposes per-category median/p90/p99 — a local-metric superset (p99 is the conventional Prometheus tail, vs C++'s trace-only p98).

type LocationResult

type LocationResult struct {
	Servers    []ServerInfo
	ShardBegin []byte
	ShardEnd   []byte
}

LocationResult holds the storage servers and shard key range for a locate() result. C++ KeyRangeLocationInfo equivalent.

type Mutation

type Mutation struct {
	Type  MutationType
	Key   []byte
	Value []byte
}

Mutation represents a key-value mutation in a transaction.

type MutationType

type MutationType uint8

MutationType is the type of mutation.

const (
	MutSetValue               MutationType = 0
	MutClearRange             MutationType = 1
	MutAddValue               MutationType = 2
	MutAnd                    MutationType = 6  // C++: And (skips DebugKeyRange=3, DebugKey=4, NoOp=5)
	MutOr                     MutationType = 7  // C++: Or
	MutXor                    MutationType = 8  // C++: Xor
	MutAppendIfFits           MutationType = 9  // C++: AppendIfFits
	MutMax                    MutationType = 12 // C++: Max (skips AvailableForReuse=10, Reserved=11)
	MutMin                    MutationType = 13 // C++: Min
	MutSetVersionstampedKey   MutationType = 14 // C++: SetVersionstampedKey
	MutSetVersionstampedValue MutationType = 15 // C++: SetVersionstampedValue
	MutByteMin                MutationType = 16 // C++: ByteMin
	MutByteMax                MutationType = 17 // C++: ByteMax
	MutMinV2                  MutationType = 18 // C++: MinV2
	MutAndV2                  MutationType = 19 // C++: AndV2
	MutCompareAndClear        MutationType = 20 // C++: CompareAndClear
)

Mutation types — MUST match C++ MutationRef::Type enum values exactly. Wire format uses these values directly. See CommitTransaction.h.

type Option

type Option func(*openOptions)

Option configures a database opened via OpenDatabase / OpenDatabaseFromConfig. Options compose and are forward-compatible — new knobs don't break callers.

func WithAPIVersion

func WithAPIVersion(v int) Option

WithAPIVersion records the selected FDB API version; required — OpenDatabase rejects an unset version, mirroring fdb_select_api_version. Gates version-dependent wire behaviour, e.g. the Min→MinV2/And→AndV2 atomic upgrade at >=510.

func WithDialFunc

func WithDialFunc(fn DialFunc) Option

WithDialFunc overrides the dialer used for every connection. nil (the default) uses a standard net.Dialer. Useful for fault injection, custom networking, or traffic shaping in tests.

func WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger sets the per-handle logger for the client's operational events (transaction retries, commit_unknown_result — RFC-097). nil (the default) uses slog.Default(), so zero-config apps keep the standard integration point (slog.SetDefault); the per-handle option exists for multi-tenant hosts and for tests, which must never mutate process-global state.

func WithRangeByteCeiling

func WithRangeByteCeiling(n int64) Option

WithRangeByteCeiling bounds how many bytes a single GetRange may materialize into memory before it fails with a *RangeMaterializationLimitError, instead of OOM-ing the process on a runaway unbounded scan. n ≤ 0 (the default) means UNLIMITED — matching libfdb_c, whose GetSliceWithError equivalent also materializes a range unbounded and never returns a "too big" error. This is a Go-only OPT-IN OOM safety valve, off by default so the default facade behavior stays oracle-matching; an operator sets a ceiling (e.g. 256<<20) as a last-resort guard. The bounded, streaming Iterator() honors StreamingMode and is the right tool for large result sets; this ceiling is the backstop for code that calls GetSliceWithError on an unexpectedly huge range. The cap bounds total materialized key+value bytes; a single read may overshoot it by at most one reply (~80 KB) before the check fires.

func WithTLSConfig

func WithTLSConfig(cfg *tls.Config) Option

WithTLSConfig connects to the cluster over TLS using the given standard *crypto/tls.Config — bring any config: in-memory certs, rotation via GetClientCertificate, custom VerifyPeerCertificate, cipher/version policy.

It takes precedence over the FDB_TLS_* environment / cluster-file ":tls" resolution and enables TLS even when the cluster string lacks ":tls". When not supplied, a ":tls" cluster string falls back to the FDB_TLS_* env convenience layer (matching the C++ client). A non-nil config is the only "use TLS" signal — there is no separate boolean, so TLS can never be silently downgraded.

WithTLSConfig(nil) is a no-op (it does NOT force plaintext): a ":tls" cluster string + FDB_TLS_* env still enables TLS. To stay plaintext, use a cluster string without ":tls".

func WithTracer

func WithTracer(t oteltrace.Tracer) Option

WithTracer sets the OpenTelemetry tracer used to EXPORT client-side trace spans (the C++ ITracer analog — NoopTracer default, pluggable backend). The pure-Go client always GENERATES + propagates a SpanContext on the wire (RFC-115 §4 Layer 1) regardless of this; WithTracer adds the export half. Pass any go.opentelemetry.io/otel/trace.Tracer (from your OTLP/Jaeger/Datadog TracerProvider); the client emits a "Transaction" span plus per-operation child spans (getValue, getRange, commit, GRV, …), seeded with the same traceID it puts on the wire so FDB server-side spans land in the same trace. nil (the default) → an internal no-op tracer: zero telemetry, zero allocation on the hot path, no OTEL SDK pulled in. Spans are recorded only for sampled transactions (see WithTracingSampleRate).

CAVEAT (span lifetime): the per-transaction "Transaction" span ends on commit success, OnError retry, Reset, or Cancel. Database.Transact/TransactCtx always hit one of these, so they are safe. A RAW Database.CreateTransaction() handle that you read from (starting the span) and then ABANDON without committing/Reset/Cancel will LEAK that span (it is never ended) — only matters with a real tracer AND a sampled transaction. Always Reset() or Cancel() a raw handle you don't commit.

func WithTracingSampleRate

func WithTracingSampleRate(rate float64) Option

WithTracingSampleRate sets the fraction (0.0–1.0) of transactions whose trace span is flagged SAMPLED. The default 0.0 matches C++ FLOW_KNOBS->TRACING_SAMPLE_RATE: every transaction still carries a real, randomly-generated SpanContext on every request (wire-faithful with C++), but flagged unsampled so collectors drop it. Raise it to emit sampled spans for a fraction of transactions. RFC-115 §4.

type PendingGet

type PendingGet struct {
	// contains filtered or unexported fields
}

PendingGet represents a GetValue request that has been sent but not yet resolved.

func (*PendingGet) Resolve

func (p *PendingGet) Resolve() ([]byte, error)

Resolve blocks until the response arrives or timeout, then applies the SAME classify/invalidate/retry semantics as the synchronous getValue path: a wrong_shard_server or all_alternatives_failed reply (including the inline LoadBalancedReply.error, RFC-010 #1) invalidates the stale location and re-drives through the full read path; transport errors, a flush failure, or a timeout likewise fall through to the full path rather than surfacing a bare error or skipping the wrong-shard retry. Pipelining only defers the wait — it must not own a different error policy. RFC-010 #3.

Flushes the write buffer on first call to ensure the request reaches the server (batched with any other deferred frames on the same connection).

type ProxyInfo

type ProxyInfo struct {
	Address string // "host:port"
	Token   transport.UID
}

ProxyInfo holds addressing info for a proxy.

type QueueModel

type QueueModel struct {
	// contains filtered or unexported fields
}

QueueModel tracks estimated outstanding request depth per storage server. Used by sendGetValue/sendGetKey/sendGetRange to pick the least-loaded server from a shard's replica set.

Matches C++ QueueModel in fdbclient/QueueModel.h: - Smoother-based continuous exponential decay (eFoldingTime=2s) - Server penalty from LoadBalancedReply - failedUntil with exponential backoff for future_version errors

Selection metric: smoothOutstanding.smoothTotal() (lower = better). C++ also uses latency for speculative second requests (secondDelay), which we don't implement yet.

type RangeMaterializationLimitError

type RangeMaterializationLimitError struct {
	LimitBytes   int64 // the configured WithRangeByteCeiling
	ReachedBytes int64 // total key+value bytes materialized when the cap was exceeded
}

RangeMaterializationLimitError is returned by a GetRange that would materialize more than the opt-in WithRangeByteCeiling cap (RFC-115 §2) — an OOM safety valve, off by default. libfdb_c has no such ceiling (its GetSliceWithError equivalent also materializes unbounded and never returns a "too big" error), so this NEVER fires unless the operator opts in via WithRangeByteCeiling; the default facade behavior stays oracle-matching. Match it with errors.As. For large scans, prefer the bounded, StreamingMode-honoring Iterator() instead of raising the ceiling.

func (*RangeMaterializationLimitError) Error

type ServerInfo

type ServerInfo struct {
	Address string
	Token   transport.UID
	// TLS records whether the SS address carried the TLS flag. Address itself stays a clean
	// host:port for dialing; GetAddressesForKey appends ":tls" to its output when this is set,
	// matching C++ NetworkAddress::toString (flow/network.cpp:215).
	TLS bool
}

ServerInfo holds a storage server's address and endpoint token.

type Snapshot

type Snapshot struct {
	// contains filtered or unexported fields
}

Snapshot wraps a Transaction for conflict-free reads. All reads go through the same transaction (same read version, same connection pool) but do not add read conflict ranges.

func (*Snapshot) Get

func (s *Snapshot) Get(ctx context.Context, key []byte) ([]byte, error)

Get reads a key without adding a read conflict range. Snapshot reads go through the RYW cache unless snapshot RYW is net-disabled (snapshotRYWDisableCount > 0).

func (*Snapshot) GetKey

func (s *Snapshot) GetKey(ctx context.Context, selectorKey []byte, orEqual bool, offset int32) ([]byte, error)

GetKey resolves a key selector without adding a read conflict range. Snapshot reads go through the snapshot cache, and — by default — SEE the txn's own pending writes (matching Snapshot.Get/GetRange and libfdb_c, where snapshot RYW is enabled unless net-disabled via SetSnapshotRYWDisable). When net-disabled (snapshotRYWDisableCount > 0) the write map is bypassed (snapshot cache only).

func (*Snapshot) GetRange

func (s *Snapshot) GetRange(ctx context.Context, begin, end []byte, limit int) ([]KeyValue, bool, error)

GetRange reads a range without adding a read conflict range. Snapshot reads go through the RYW cache unless snapshot RYW is net-disabled (snapshotRYWDisableCount > 0).

func (*Snapshot) GetRangeReverse

func (s *Snapshot) GetRangeReverse(ctx context.Context, begin, end []byte, limit int) ([]KeyValue, bool, error)

GetRangeReverse reads a range in reverse without adding a read conflict range. Snapshot reads go through the RYW cache unless snapshot RYW is net-disabled (snapshotRYWDisableCount > 0).

func (*Snapshot) GetReadVersion

func (s *Snapshot) GetReadVersion(ctx context.Context) (int64, error)

GetReadVersion returns the read version for this transaction via its snapshot view.

type Transaction

type Transaction struct {
	// contains filtered or unexported fields
}

Transaction represents an FDB transaction. Mutations are buffered locally and sent on Commit().

func (*Transaction) AddReadConflictKey

func (tx *Transaction) AddReadConflictKey(key []byte)

AddReadConflictKey adds a read conflict on a single key. Like AddReadConflictRange it is filtered through the RYW write-map (C++ addReadConflictRange over [key, keyAfter(key)) → updateConflictMap, ReadYourWrites.actor.cpp:1986): a self-written independent key adds no conflict; rywDisabled adds the full single-key conflict directly (:1979). Identical to the Get-path helper, so delegate.

func (*Transaction) AddReadConflictRange

func (tx *Transaction) AddReadConflictRange(begin, end []byte) error

AddReadConflictRange adds an explicit read conflict range [begin, end). If any key in this range is modified by another transaction between this transaction's read version and commit, the commit will fail. Returns inverted_range (2005) if begin > end. Matches C++ fdb_transaction_add_conflict_range.

func (*Transaction) AddWriteConflictKey

func (tx *Transaction) AddWriteConflictKey(key []byte)

AddWriteConflictKey adds a write conflict on a single key.

func (*Transaction) AddWriteConflictRange

func (tx *Transaction) AddWriteConflictRange(begin, end []byte) error

AddWriteConflictRange adds an explicit write conflict range [begin, end). Returns inverted_range (2005) if begin > end. Matches C++ fdb_transaction_add_conflict_range.

func (*Transaction) Atomic

func (tx *Transaction) Atomic(op MutationType, key, operand []byte)

Atomic performs an atomic mutation.

func (*Transaction) AwaitWatchCommit

func (tx *Transaction) AwaitWatchCommit(watchCtx context.Context, act *watchActivation, readVersion int64) (int64, error)

AwaitWatchCommit blocks until the watch's captured incarnation resolves, returning the version to register the watch at — committedVersion, or readVersion when the txn didn't commit (C++ setupWatches' `committedVersion > 0 ? committedVersion : readVersion`, NativeAPI.actor.cpp:6420). Returns an error when the watch is abandoned (reset/Cancel → 1025) or its scoped context is cancelled, so the facade drains without registering. RFC-170 (#8): the async facade calls this BEFORE WatchPoll.

func (*Transaction) BypassUnreadable

func (tx *Transaction) BypassUnreadable() bool

BypassUnreadable reports whether FDB_TR_OPTION_BYPASS_UNREADABLE is set. Read-only accessor used to verify database-level option propagation.

func (*Transaction) Cancel

func (tx *Transaction) Cancel()

Cancel cancels the transaction. All subsequent operations will return an error. This is irreversible — a cancelled transaction cannot be reused.

func (*Transaction) CausalReadRisky

func (tx *Transaction) CausalReadRisky() bool

CausalReadRisky reports whether the GRV causal-read-risky flag is set. Read-only accessor used to verify database-level option propagation.

func (*Transaction) Clear

func (tx *Transaction) Clear(key []byte)

func (*Transaction) ClearRange

func (tx *Transaction) ClearRange(begin, end []byte) error

ClearRange deletes all keys in [begin, end). Returns inverted_range (2005) if begin > end. Matches C++ fdb_transaction_clear_range_impl. Zero-width ranges (begin == end) are silently ignored, matching C++.

func (*Transaction) Commit

func (tx *Transaction) Commit(ctx context.Context) error

Commit sends mutations to a commit proxy. After successful commit, the transaction is automatically reset for reuse (mutations and conflict ranges cleared, read version invalidated). This matches the C client's behavior where fdb_transaction_set() can be called after commit to start building a new transaction.

func (*Transaction) EnsureMutationCapacity

func (tx *Transaction) EnsureMutationCapacity(n int)

EnsureMutationCapacity pre-sizes the mutations and writeConflicts slices to avoid growth allocations during batch writes. Call before a large batch.

func (*Transaction) Get

func (tx *Transaction) Get(ctx context.Context, key []byte) ([]byte, error)

Get reads a single key. Returns nil if the key doesn't exist.

func (*Transaction) GetAddressesForKey

func (tx *Transaction) GetAddressesForKey(parentCtx context.Context, key []byte) ([]string, error)

GetAddressesForKey returns the addresses of storage servers responsible for the given key. Uses the location cache (queries cluster on miss).

func (*Transaction) GetApproximateSize

func (tx *Transaction) GetApproximateSize() (int64, error)

GetApproximateSize returns the approximate size of the transaction's mutations and conflict ranges in bytes. Matches C++ ReadYourWritesTransaction accounting: each mutation includes sizeof(MutationRef), each conflict range includes sizeof(KeyRangeRef). For set/atomic with write conflicts, C++ also adds the key length again for the auto-generated write conflict range.

func (*Transaction) GetCommittedVersion

func (tx *Transaction) GetCommittedVersion() (int64, error)

GetCommittedVersion returns the version at which this transaction committed.

func (*Transaction) GetEstimatedRangeSizeBytes

func (tx *Transaction) GetEstimatedRangeSizeBytes(parentCtx context.Context, begin, end []byte) (int64, error)

GetEstimatedRangeSizeBytes returns an estimate of the byte size of the given key range. Matches C++ getStorageMetricsLargeKeyRange in NativeAPI.actor.cpp: gets all shard locations, sends WaitMetricsRequest to each with min.bytes=0, max.bytes=-1 (reversed range = immediate response), and sums the bytes.

func (*Transaction) GetKey

func (tx *Transaction) GetKey(ctx context.Context, selectorKey []byte, orEqual bool, offset int32) ([]byte, error)

GetKey resolves a key selector to the actual key in the database.

func (*Transaction) GetLocations

func (tx *Transaction) GetLocations(parentCtx context.Context, begin, end []byte, limit int) ([]LocationResult, error)

GetLocations returns all shard location entries overlapping [begin, end).

func (*Transaction) GetPipelined

func (tx *Transaction) GetPipelined(ctx context.Context, key []byte) (val []byte, pending *PendingGet, err error)

GetPipelined sends a GetValue request and returns a PendingGet that can be resolved later. This enables true pipelining: send N requests without waiting, then collect all N responses. Matches C++ client pipelining.

Returns (nil, nil, nil) for RYW cache hits (value is returned in val). Returns (nil, pending, nil) for server requests (call pending.Resolve() to get value). Returns (nil, nil, err) for errors during send.

func (*Transaction) GetRange

func (tx *Transaction) GetRange(ctx context.Context, begin, end []byte, limit int) ([]KeyValue, bool, error)

GetRange reads a range of keys [begin, end) in forward order.

func (*Transaction) GetRangeReverse

func (tx *Transaction) GetRangeReverse(ctx context.Context, begin, end []byte, limit int) ([]KeyValue, bool, error)

GetRangeReverse reads a range of keys [begin, end) in reverse order. Matches C++ where negative limit = reverse scan.

func (*Transaction) GetRangeSplitPoints

func (tx *Transaction) GetRangeSplitPoints(parentCtx context.Context, begin, end []byte, chunkSize int64) ([][]byte, error)

GetRangeSplitPoints returns suggested split points for the given key range. Matches C++ Transaction::getRangeSplitPoints in NativeAPI.actor.cpp.

func (*Transaction) GetReadVersion

func (tx *Transaction) GetReadVersion(ctx context.Context) (int64, error)

GetReadVersion returns the read version for this transaction, fetching it from a GRV proxy if not already set. Matches C++ fdb_transaction_get_read_version.

func (*Transaction) GetTagThrottledDuration

func (tx *Transaction) GetTagThrottledDuration() float64

GetTagThrottledDuration returns the total time this transaction was delayed by proxy tag throttling across all GRV requests. Matches C++ Transaction::getTagThrottledDuration() (NativeAPI.actor.cpp:7594).

func (*Transaction) GetVersionstamp

func (tx *Transaction) GetVersionstamp() ([]byte, error)

GetVersionstamp returns the 10-byte versionstamp from the committed transaction. Format: [version 8 bytes big-endian][txnBatchId 2 bytes big-endian]. Must be called after a successful Commit.

func (*Transaction) LockAware

func (tx *Transaction) LockAware() bool

LockAware reports whether the commit is lock-aware (sets FLAG_IS_LOCK_AWARE, bypassing the locked-database check). Mirrors SetLockAware.

func (*Transaction) OnError

func (tx *Transaction) OnError(ctx context.Context, err error) (rerr error)

OnError handles a transaction error. Returns nil if the error is retryable (the transaction has been reset for retry). Returns the error if non-retryable or ctx.Err() if ctx fires during the backoff sleep.

func (*Transaction) ReadLockAware

func (tx *Transaction) ReadLockAware() bool

ReadLockAware reports whether reads bypass the locked-database check. Mirrors SetReadLockAware.

func (*Transaction) ReleaseWatch

func (tx *Transaction) ReleaseWatch()

ReleaseWatch releases the outstanding-watch slot WatchSetup reserved (C++ decreaseWatchCounter). It is normally released by WatchPoll on completion, but when AwaitWatchCommit aborts a watch BEFORE it reaches WatchPoll (never-committed / reset / Cancel / ctx-expiry), WatchPoll never runs — so the async facade calls this on that abort path, else the slot leaks and later watches fail with too_many_watches under MAX_WATCHES. Idempotent-safe by construction: WatchPoll runs only on the success path, this only on the abort path — never both for one watch.

func (*Transaction) Reset

func (tx *Transaction) Reset()

Reset resets the transaction to a clean state, as if newly created from Database. Unlike the internal reset() used by OnError (which preserves retryCount/backoff), this clears everything including retry state. Options set via Set*() are preserved across Reset, matching C++ ReadYourWritesTransaction::reset() + applyPersistentOptions. Updates creationTime so the timeout budget restarts (matches C++ reset() behavior).

In-flight Watch() calls ARE cancelled by Reset() (via reset()→cancelWatches(), below), but they surface as context.Canceled rather than the FDBError transaction_cancelled (1025) C++ raises via resetPromise.sendError — a known divergence (TODO "watch-path divergences" D5).

func (*Transaction) Set

func (tx *Transaction) Set(key, value []byte)

Set writes a key-value pair.

func (*Transaction) SetAccessSystemKeys

func (tx *Transaction) SetAccessSystemKeys()

SetAccessSystemKeys allows reading AND writing \xff prefix system keys.

func (*Transaction) SetBypassUnreadable

func (tx *Transaction) SetBypassUnreadable(v bool)

SetBypassUnreadable mirrors FDB_TR_OPTION_BYPASS_UNREADABLE (ReadYourWrites.actor.cpp:2611-2613): reads of keys with pending versionstamped writes return the write-map value with the placeholder bytes as written instead of failing with accessed_unreadable (1036); SVK's unmodified-unreadable candidate range reads through to storage. RFC-098.

func (*Transaction) SetCausalReadRisky

func (tx *Transaction) SetCausalReadRisky(v bool)

SetCausalReadRisky sets the causal-read-risky flag. When set, the read version may not reflect the latest committed writes.

func (*Transaction) SetLockAware

func (tx *Transaction) SetLockAware(v bool)

SetLockAware sets the lock-aware flag on the commit request.

func (*Transaction) SetMaxRetryDelay

func (tx *Transaction) SetMaxRetryDelay(ms int64)

SetMaxRetryDelay caps the exponential backoff between retries. Value in milliseconds. Matches C++ FDB_TR_OPTION_MAX_RETRY_DELAY.

func (*Transaction) SetNextWriteNoWriteConflictRange

func (tx *Transaction) SetNextWriteNoWriteConflictRange()

SetNextWriteNoWriteConflictRange causes the next mutation to NOT add a write conflict range. Auto-resets after one mutation. Matches C++ FDB_TR_OPTION_NEXT_WRITE_NO_WRITE_CONFLICT_RANGE.

func (*Transaction) SetPriority

func (tx *Transaction) SetPriority(p TransactionPriority)

SetPriority sets the transaction priority for GRV requests.

func (*Transaction) SetReadLockAware

func (tx *Transaction) SetReadLockAware(v bool)

SetReadLockAware allows reads on locked databases without granting commit access. C++: options.readLockAware — only affects read path.

func (*Transaction) SetReadSystemKeys

func (tx *Transaction) SetReadSystemKeys()

SetReadSystemKeys allows reading \xff prefix system keys.

func (*Transaction) SetReadVersion

func (tx *Transaction) SetReadVersion(version int64)

SetReadVersion sets the read version manually.

func (*Transaction) SetReadYourWritesDisable

func (tx *Transaction) SetReadYourWritesDisable()

SetReadYourWritesDisable disables RYW for regular (non-snapshot) reads. When set, Get/GetRange always read from the server, ignoring uncommitted writes. Matches FDB_TR_OPTION_READ_YOUR_WRITES_DISABLE.

libfdb_c forbids setting this option after any read or write: RYW setOptionImpl throws client_invalid_operation BEFORE assigning the option (ReadYourWrites.actor.cpp:2534-2542), so the option does NOT take effect; the throw lands in deferredError (the option call itself succeeds) and every subsequent op returns 2000 until reset (RFC-059). Match both halves: record the deferred error AND leave rywDisabled unset. A clean (pre-op) disable applies normally.

func (*Transaction) SetRetryLimit

func (tx *Transaction) SetRetryLimit(retries int64)

SetRetryLimit limits the number of retries in OnError. A value of 0 means "don't retry at all" (first error escapes). A value of -1 means "unlimited" (default behavior). Matches C++ FDB_TR_OPTION_RETRY_LIMIT.

func (*Transaction) SetSizeLimit

func (tx *Transaction) SetSizeLimit(limit int64)

SetSizeLimit sets the maximum transaction size in bytes. If the transaction exceeds this size, commit returns error 2101. Valid range: [32, 10_000_000]. Out-of-range values cause error 2006 at commit. A value of 0 disables the limit.

func (*Transaction) SetSkipGrvCache

func (tx *Transaction) SetSkipGrvCache()

SetSkipGrvCache forces this transaction to bypass the GRV cache even if SetUseGrvCache was also set (SKIP_GRV_CACHE, 1102 — skip wins). RFC-104.

func (*Transaction) SetSnapshotRYWDisable

func (tx *Transaction) SetSnapshotRYWDisable()

SetSnapshotRYWDisable decrements the snapshot-RYW enable count (stored as the disabled-oriented inverse, so it increments here). Matches FDB_TR_OPTION_SNAPSHOT_RYW_DISABLE (libfdb_c does enabledCount--). When the net count is > 0 (more disables than enables), Snapshot.Get/GetRange/GetKey read from the server, bypassing the RYW cache.

func (*Transaction) SetSnapshotRYWDisableCount

func (tx *Transaction) SetSnapshotRYWDisableCount(n int)

SetSnapshotRYWDisableCount SETS the snapshot-RYW disable counter to n (vs the ++/-- of SetSnapshotRYWDisable/Enable). It seeds the per-tx counter to a database default. Setting (not incrementing) is idempotent under the retry replay of applyTxDefaults — matching libfdb_c, whose reset() re-seeds snapshotRywEnabled = db->snapshotRywEnabled each attempt rather than accumulating.

func (*Transaction) SetSnapshotRYWEnable

func (tx *Transaction) SetSnapshotRYWEnable()

SetSnapshotRYWEnable re-enables RYW for snapshot reads, undoing one prior SetSnapshotRYWDisable. Matches FDB_TR_OPTION_SNAPSHOT_RYW_ENABLE (libfdb_c does enabledCount++). The option is a counter, not a toggle: two disables require two enables to re-enable, and an enable from the default pushes the count negative (still enabled).

func (*Transaction) SetSpanParent

func (tx *Transaction) SetSpanParent(b []byte) error

SetSpanParent injects a parent trace context (FDBTransactionOptions::SPAN_PARENT, NativeAPI.actor.cpp:7126): a 33-byte IncludeVersion-serialized SpanContext. The transaction's span becomes a child of it (inherit traceID + flags, fresh spanID), and the linkage persists across retries (regenerateSpan honors spanParent).

func (*Transaction) SetTag

func (tx *Transaction) SetTag(tag string)

SetTag adds a tag to this transaction for tag-based throttling. Tags are used for throttle backoff calculation on tag_throttled errors. Matches C++ FDB_TR_OPTION_AUTO_THROTTLE_TAG / FDB_TR_OPTION_DEBUG_TRANSACTION_IDENTIFIER usage.

func (*Transaction) SetTenantId

func (tx *Transaction) SetTenantId(id int64)

SetTenantId sets the tenant for this transaction. All operations will be scoped to the tenant's key space. Use NoTenantID (-1) for no tenant.

func (*Transaction) SetTimeout

func (tx *Transaction) SetTimeout(ms int64)

SetTimeout sets a timeout in milliseconds for this transaction. The timeout is an overall budget from creation time (or last user Reset), NOT per-retry. OnError retries share the same deadline. A value of 0 disables the timeout. Matches C++ FDB_TR_OPTION_TIMEOUT.

func (*Transaction) SetUseGrvCache

func (tx *Transaction) SetUseGrvCache()

SetUseGrvCache opts this transaction in to serving its read version from the database's GRV cache (USE_GRV_CACHE, 1101). Off by default — a default transaction issues a fresh proxy GRV, matching libfdb_c. RFC-104.

func (*Transaction) SetWriteConflictsDisabled

func (tx *Transaction) SetWriteConflictsDisabled()

SetWriteConflictsDisabled disables write conflict ranges for all subsequent mutations. Use for insert-only batch writes where keys are guaranteed unique and all atomic operations commute (ADD, MAX, MIN). Significantly reduces commit request size and eliminates conflict buffer allocations.

func (*Transaction) Snapshot

func (tx *Transaction) Snapshot() *Snapshot

Snapshot returns a snapshot view of this transaction. Snapshot reads do not add read conflict ranges, so they don't cause conflicts with concurrent writers. Same read version, same connection.

func (*Transaction) SnapshotRYWDisableCount

func (tx *Transaction) SnapshotRYWDisableCount() int

SnapshotRYWDisableCount reports the net snapshot-RYW-disable count (> 0 means snapshot reads bypass the RYW cache). Read-only accessor used to verify database-level option propagation.

func (*Transaction) TenantId

func (tx *Transaction) TenantId() int64

TenantId returns the current tenant ID for this transaction. Returns NoTenantID (-1) if no tenant is set.

func (*Transaction) Watch

func (tx *Transaction) Watch(ctx context.Context, key []byte) error

Watch watches a key for changes. The server holds the connection open until the watched key's value changes from the version observed by this transaction. Returns nil when the key has changed, or an error on failure.

Matches C++ NativeAPI.actor.cpp watchValueMap/watchValue flow: locate storage server, send WatchValueRequest with current read version, long-poll for WatchValueReply. Retries on wrong_shard_server with cache invalidation.

The watch is a long-poll: there is no short timeout. The context's deadline (if any) controls the maximum wait time. RFC-170 (#8) note: this SYNCHRONOUS client API registers the watch at the READ version — it blocks in WatchPoll until the watch fires, so it cannot wait for a commit that (by construction) can only happen AFTER it returns. The committed-version deferral (register post-commit) is done by the ASYNC fdb facade Watch (which returns a future and blocks that future's goroutine on the commit-completion signal). Callers of this sync API that need committed-version semantics must commit before/around the watch (C++ setupWatches' committedVersion>0?committedVersion:readVersion applies at the facade, not here).

func (*Transaction) WatchActivation

func (tx *Transaction) WatchActivation() *watchActivation

WatchActivation returns this incarnation's activation, lazily creating it on first use (a fresh handle before any Watch/commit has nil watchAct). Race-safe via CAS so two concurrent Watch() calls share one.

func (*Transaction) WatchPoll

func (tx *Transaction) WatchPoll(watchCtx context.Context, watchCancel context.CancelFunc, key, value []byte, readVersion int64, span types.SpanContext) error

WatchPoll performs the ASYNCHRONOUS long-poll part of a watch: locate the storage server and wait for the WatchValueReply that fires when key's value differs from `value` (captured by WatchSetup), registered at `readVersion` (also captured by WatchSetup — NOT re-read from the possibly-reset transaction). Retries on wrong_shard_server with cache invalidation. Intended to run in the watch future's goroutine.

func (*Transaction) WatchSetup

WatchSetup performs the SYNCHRONOUS part of a watch: pin the read version, add the read conflict, and read the value to watch — all at the transaction's read version. It returns BOTH the value bytes and the read version the watch must be registered against.

This MUST run within the watching transaction's active window (e.g. directly from Transaction.Watch, not from a detached goroutine that races later mutations). Two things are captured here, both for the same reason:

  • the VALUE: if read late — after some other transaction already changed the key — the storage server would be told to watch the *new* value, see the current value already equals it, and never fire (a silent 10s-timeout flake);
  • the READ VERSION: the async WatchPoll's sendWatch must NOT read tx.readVersion later, because the common `w := tr.Watch(k)` inside Database.Transact pattern commits and postCommitReset()s the transaction (readVersion → 0) before the future goroutine runs — sending the watch at version 0, which can error or register incorrectly. So the read version is captured synchronously here and threaded through to sendWatch.

type TransactionDefaults

type TransactionDefaults struct {
	Timeout        int64 // FDB_DB_OPTION_TRANSACTION_TIMEOUT (ms), 0 = disabled
	RetryLimit     int   // FDB_DB_OPTION_TRANSACTION_RETRY_LIMIT
	MaxRetryDelay  int64 // FDB_DB_OPTION_TRANSACTION_MAX_RETRY_DELAY (ms), 0 = use default
	SizeLimit      int64 // FDB_DB_OPTION_TRANSACTION_SIZE_LIMIT; 0/unset → 10 MB default (C++ has no "disabled" state)
	HasRetryLimit  bool
	ReadSystemKeys bool // read \xff/* keys by default
	AccessSysKeys  bool // read+write \xff/* keys by default
}

TransactionDefaults holds database-level defaults applied to every new transaction. Matches C++ DatabaseContext::transactionDefaults.

type TransactionPriority

type TransactionPriority int

TransactionPriority controls the GRV request priority. C++ GetReadVersionRequest::Flags encoding.

const (
	PriorityDefault TransactionPriority = iota
	PriorityBatch
	PrioritySystemImmediate
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL