Class EntityIdempotency
Instead of persisting idempotency records in a dedicated store, this model stamps the
idempotency key directly onto the internalProperties of the entity produced by the
originating operation. Because the key is part of the same writeEntity call that creates
(or updates) the entity, the key and the operation commit atomically in a single transaction —
there is no "record-after-success" gap where the entity is committed but a separate idempotency
write is lost.
The keys are stored under a single reserved internal-properties key (IDEMPOTENCY_KEYS_PROPERTY), encoded as the IS1 version marker followed by a base64url
SMILE array of (key, expiryMillis) entries. Entries use single-character property names
(k, e) to keep the serialized window small. The version prefix leaves room to
evolve the encoding later without ambiguity.
For createTable this window holds a single entry, but the shape generalizes to a
per-entity window for repeated mutations (e.g. updateTable). The window is bounded only
by expiry (TTL): expired keys are dropped inline whenever the entity is rewritten (recordKey(java.util.Map<java.lang.String, java.lang.String>, java.util.UUID, java.time.Instant, java.time.Instant)), and expiry is also honored at read time (hasLiveKey(java.util.Map<java.lang.String, java.lang.String>, java.util.UUID, java.time.Instant)) so a
stale-but-not-yet-purged key is treated as absent. Live keys are never evicted by count; a large
safety ceiling (MAX_LIVE_KEYS) bounds the window by failing the write rather than
dropping a still-live key.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringInternal-properties key under which the per-entity idempotency key window is stored. -
Method Summary
Modifier and TypeMethodDescriptionstatic booleanReturnstrueifkeyis recorded on the given internal properties and has not yet expired as ofnow.Returns a copy ofinternalPropertieswithkeyrecorded (expiring atexpiry) and any keys already expired as ofnowdropped.
-
Field Details
-
IDEMPOTENCY_KEYS_PROPERTY
Internal-properties key under which the per-entity idempotency key window is stored.- See Also:
-
-
Method Details
-
hasLiveKey
Returnstrueifkeyis recorded on the given internal properties and has not yet expired as ofnow. -
recordKey
public static Map<String,String> recordKey(Map<String, String> internalProperties, UUID key, Instant expiry, Instant now) Returns a copy ofinternalPropertieswithkeyrecorded (expiring atexpiry) and any keys already expired as ofnowdropped. This is the inline purge-on-write step: it runs within the same transaction that persists the entity, so no separate maintenance pass is required.The window is bounded only by expiry (TTL), never by a count-based eviction: a live key is never evicted to make room. Evicting a still-live key would silently disable idempotency for it and reintroduce the corruption failure mode (a retry would re-run and could 409), so under a high write rate we accept a larger window rather than dropping keys that could still be retried. A large safety ceiling (
MAX_LIVE_KEYS) still bounds the window: when it is reached the write fails with a retryablePolarisServiceUnavailableException(HTTP 503 with aRetry-After) instead of dropping a key.
-