Stores¶
TidStore ¶
Bases: Protocol
Structural Protocol for tRFC/qRFC TID duplicate-execution guards (D-01).
Implementers provide a durable backend (database, Redis, …). Clients that implement all five methods satisfy this Protocol without any inheritance (structural / duck-typing — D-01 / PEP 544).
Security contract (T-06-S01)¶
tid values are peer-influenced 24-character strings from the RFC TID
alphabet (ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/_=@-). Treat tid as
untrusted input: use parameterised queries; never concatenate tid
into SQL strings or file paths. Length is expected to be 24 chars
(RFC_TID_LN in SDK type definitions) but the store MUST NOT silently normalise
or truncate — document any length enforcement as part of the backend contract.
Source code in src/saprfclib/stores.py
is_executed ¶
mark_received ¶
mark_executed ¶
mark_rolled_back ¶
confirm ¶
park ¶
Store serialised request bytes alongside TID state for later re-drive (D-03b).
bytes(payload) copies are stored — caller mutations to the source
buffer do not affect the stored payload.
Security contract (T-06-S01): tid is peer-influenced untrusted input.
Use parameterised queries; never concatenate tid into SQL or file paths.
Source code in src/saprfclib/stores.py
get_parked ¶
Return the parked payload for tid, or None if not parked (D-03b).
Security contract (T-06-S01): tid is peer-influenced untrusted input.
Use parameterised queries; never concatenate tid into SQL or file paths.
Source code in src/saprfclib/stores.py
list_parked ¶
delete_parked ¶
Remove the parked payload for tid; get_parked then returns None (D-03b).
Security contract (T-06-S01): tid is peer-influenced untrusted input.
Use parameterised queries; never concatenate tid into SQL or file paths.
Source code in src/saprfclib/stores.py
UnitStore ¶
Bases: Protocol
Structural Protocol for bgRFC Unit lifecycle tracking (D-02).
Keyed on (unit_id, unit_type) where unit_type is 'T' (no queues)
or 'Q' (queues — Pitfall 5 from RESEARCH.md). Implementers must handle
both unit types; the type is part of the key because the same unit_id
MUST be tracked separately per type in the bgRFC protocol.
Security contract (T-06-S01)¶
unit_id values are peer-influenced 32-character uppercase hex strings
(RFC_UNITID_LN in SDK type definitions). Treat as untrusted input: use
parameterised queries; never concatenate into SQL or file paths.
unit_type is 'T' or 'Q'; validate before use.
Source code in src/saprfclib/stores.py
get_unit_state ¶
Return the current :class:UnitState for (unit_id, unit_type).
Returns UnitState.NOT_FOUND for unknown units.
persist ¶
confirm ¶
park ¶
Store serialised request bytes for (unit_id, unit_type) (D-03b).
bytes(payload) copies are stored — caller mutations do not affect
the stored payload.
Security contract (T-06-S01): unit_id / unit_type are
peer-influenced untrusted inputs. Use parameterised queries; never
concatenate into SQL or file paths.
Source code in src/saprfclib/stores.py
get_parked ¶
Return the parked payload for (unit_id, unit_type), or None (D-03b).
Security contract (T-06-S01): unit_id / unit_type are
peer-influenced untrusted inputs.
Source code in src/saprfclib/stores.py
list_parked ¶
delete_parked ¶
Remove the parked payload for (unit_id, unit_type) (D-03b).
Security contract (T-06-S01): unit_id / unit_type are
peer-influenced untrusted inputs.
UnitState ¶
Bases: Enum
Processing state of a bgRFC Unit on the receiver side (RFC_UNIT_STATE).
Maps the five values from RFC_UNIT_STATE in SDK type definitions-332. The
string values mirror the ServerSessionState style used elsewhere in
this package (consistent string-valued enum.Enum pattern).
Values¶
NOT_FOUND (0)
No information for this unit in the target system. The send may have
not reached the target; re-send is appropriate unless CONFIRMED
was already seen.
IN_PROCESS (1)
Backend is persisting (type 'Q') or executing (type 'T') the payload.
Wait and poll again.
COMMITTED (2)
Data persisted (or executed) on the receiver. Confirm event may be sent.
ROLLED_BACK (3)
An error occurred; unit must be re-sent.
CONFIRMED (4)
Temporary state after Confirm and before status erasure. No action needed;
delete payload and status information on the sender side.
Source code in src/saprfclib/stores.py
InMemoryTidStore ¶
Thread-safe in-process TID store backed by a dict + threading.Lock.
Process-lifetime only — NOT durable (D-03). Data is lost on process restart.
Production deployments must supply a custom durable store (e.g. PostgreSQL,
Redis) that satisfies the :class:TidStore Protocol.
Security (T-06-S01): TID keys are stored as-is in a Python dict. This is safe for dict keys; it is the responsibility of durable backend implementers to treat TID values as untrusted (parameterised queries, no concatenation).
Concurrency (T-06-S03): a single threading.Lock guards all mutations.
Source code in src/saprfclib/stores.py
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | |
is_executed ¶
mark_received ¶
mark_executed ¶
mark_rolled_back ¶
confirm ¶
park ¶
Store a copy of payload for later re-drive (D-03b).
Does not alter TID state — is_executed() is unaffected.
Security (T-06-S01): tid is peer-influenced untrusted input; used
only as a Python dict key here (safe for in-process stores).
Source code in src/saprfclib/stores.py
get_parked ¶
Return parked payload for tid, or None if not parked (D-03b).
Security (T-06-S01): tid used as Python dict key only (safe).
list_parked ¶
delete_parked ¶
Remove the parked payload for tid (D-03b).
Security (T-06-S01): tid used as Python dict key only (safe).
InMemoryUnitStore ¶
Thread-safe in-process bgRFC Unit store backed by a dict + threading.Lock.
Process-lifetime only — NOT durable (D-03). Data is lost on process restart.
Production deployments must supply a custom durable store that satisfies the
:class:UnitStore Protocol.
Unit state key is (unit_id, unit_type) so that the same unit_id
may coexist with different types (Pitfall 5 — 'T' and 'Q' are distinct).
Security (T-06-S01): keys stored as-is in a Python dict; safe for in-process use. Durable backend implementers must parameterise all queries.
Concurrency (T-06-S03): a single threading.Lock guards all mutations.
Source code in src/saprfclib/stores.py
get_unit_state ¶
Return the :class:UnitState for (unit_id, unit_type).
Returns :attr:UnitState.NOT_FOUND for unknown units.
Source code in src/saprfclib/stores.py
persist ¶
Persist Unit; set state to :attr:UnitState.IN_PROCESS.
confirm ¶
park ¶
Store a copy of payload for (unit_id, unit_type) (D-03b).
Does not alter unit state — get_unit_state() is unaffected.
Security (T-06-S01): keys used as Python tuple dict keys only (safe).
Source code in src/saprfclib/stores.py
get_parked ¶
Return parked payload for (unit_id, unit_type), or None (D-03b).
list_parked ¶
delete_parked ¶
Remove the parked payload for (unit_id, unit_type) (D-03b).
Security (T-06-S01): keys used as Python tuple dict keys only (safe).