Interface ReplayCache
- All Known Implementing Classes:
InMemoryReplayCache
A consumer wires a ReplayCache to narrow a token/identifier that would otherwise be usable any number
of times within its lifetime down to single-use: the second and every subsequent submission of the same
identifier is reported as a replay. The SPI is deliberately generic — it deals only in a String
identifier and a
Atomic check-and-record (no TOCTOU). checkAndRecord(String, long) both checks whether an
identifier has been seen before and records it as seen, as one indivisible operation. A separate
"seen" followed by a separate "record" would leave a race window in which two near-simultaneous submissions of
the same identifier could both observe "not yet seen" and both proceed; implementations must guarantee that of
any two concurrent calls with the same identifier, at most one returns
Fail-mode is a consumer decision. When the backing store cannot answer — for example a remote
store is unreachable — an implementation may either throw or return an outcome. The consumer decides how
a thrown failure is resolved by passing a ReplayCache.FailMode to
checkAndRecord(String, long, FailMode, Consumer):
ReplayCache.FailMode.FAIL_CLOSED(the safe default) treats a store failure as a replay (reject).ReplayCache.FailMode.FAIL_OPENtreats a store failure as first-seen (allow), degrading to the multi-use-tolerant behavior a consumer would have with noReplayCachewired at all.
ReplayCache.FailMode) can catch its own failures internally and return checkAndRecord(String, long) instead of throwing.
The built-in default is per-process only. The zero-config built-in implementation
(InMemoryReplayCache) is backed by process-local memory, so it only enforces single-use within one
process. Cross-node single-use requires a consumer-supplied ReplayCache backed by a store shared
across every node.
See Also:
- Since:
- 10.0.0
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic enumThe policy applied bycheckAndRecord(String, long, FailMode, Consumer)whencheckAndRecord(String, long)throws (the backing store could not answer). -
Method Summary
Modifier and TypeMethodDescriptionbooleancheckAndRecord(String id, long expiresAtMs) Atomically checks whether the specified identifier has been observed before and records it as seen if not.default booleancheckAndRecord(String id, long expiresAtMs, ReplayCache.FailMode failMode) InvokescheckAndRecord(String, long)applying the specified fail-mode policy on a thrown failure.default booleancheckAndRecord(String id, long expiresAtMs, ReplayCache.FailMode failMode, Consumer<Exception> onFailure) InvokescheckAndRecord(String, long)applying the specified fail-mode policy on a thrown failure.
-
Method Details
-
checkAndRecord
Atomically checks whether the specified identifier has been observed before and records it as seen if not.Implementations own their own timeout. A call that blocks indefinitely (for example a remote store with no client-side deadline) blocks the caller with it. An implementation backed by a network store must bound its own call so a slow/unreachable backend surfaces promptly as a throw (which the caller resolves per its chosen
ReplayCache.FailMode) or a return, never an unbounded stall.- Parameters:
id- The identifier to check. Nevernull .expiresAtMs- The identifier's own absolute expiry, in epoch milliseconds. An implementation may use this to self-evict a record once it can no longer matter.- Returns:
true if this is the first time the identifier has been observed (the caller should proceed);false if it has been observed before (the caller should reject the submission as a replay).
-
checkAndRecord
InvokescheckAndRecord(String, long)applying the specified fail-mode policy on a thrown failure.Equivalent to
checkAndRecord(id, expiresAtMs, failMode,.null )- Parameters:
id- The identifier to check. Nevernull .expiresAtMs- The identifier's own absolute expiry, in epoch milliseconds.failMode- The policy to apply ifcheckAndRecord(String, long)throws. Must not benull .- Returns:
true if the caller should proceed;false if the submission should be rejected.
-
checkAndRecord
default boolean checkAndRecord(String id, long expiresAtMs, ReplayCache.FailMode failMode, Consumer<Exception> onFailure) InvokescheckAndRecord(String, long)applying the specified fail-mode policy on a thrown failure.If
checkAndRecord(String, long)throws, the exception is passed toonFailure (when non-null ) and then resolved totrue forReplayCache.FailMode.FAIL_OPENorfalse forReplayCache.FailMode.FAIL_CLOSED.- Parameters:
id- The identifier to check. Nevernull .expiresAtMs- The identifier's own absolute expiry, in epoch milliseconds.failMode- The policy to apply ifcheckAndRecord(String, long)throws. Must not benull .onFailure- A handler invoked with the thrown exception before the policy is applied. Can benull .- Returns:
true if the caller should proceed;false if the submission should be rejected.
-