Repository navigation
feat(idempotency): support custom key prefixes in annotation and functional APIs - #2720
Open
hidingmyname wants to merge 1 commit into
Open
hidingmyname wants to merge 1 commit into
hidingmyname wants to merge 1 commit into
Conversation
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Changes
Add an optional custom idempotency key prefix to both public entry points. A non-empty prefix replaces the complete default
{lambdaFunctionName}.{functionName}namespace; the payload hash and key separator stay unchanged. This allows records to survive method or Lambda renames and allows intentionally shared idempotency scopes.@Idempotent(keyPrefix = "create-order").String keyPrefixoverload for all sixmakeIdempotentforms: default/namedSupplierandFunction, each withClassandTypeReferencereturn types.makeIdempotent,IdempotencyHandler, andBasePersistenceStore.configuresignatures; add corresponding handler/store overloads.Issue number: Fixes #2718
Maintainer acceptance mapping
Idempotent.keyPrefix()is propagated by the aspect through the new handler overloads; all existing functional API forms have matching trailing-prefix overloads.handle(), and all six original functional overloads remain. The new store overload invokes the original virtual method, preserving initialization hooks in existing custom persistence subclasses. Regressions execute both original handler constructors and prove that a subclass-selected payload key still suppresses duplicate execution for omitted, empty, and custom prefixes.IdempotencyKeyPrefixTest: all six new overloads, persisted keys and completed status, duplicate execution suppression, typed generic results, renamed functions sharing a prefix, unrelated prefixes remaining independent, original handler constructors, and cross-entry local-cache reuse.IdempotencyAspectTest: actual woven annotation invocation, shared-prefix replay across methods, distinct-prefix separation, and default/empty annotation behavior with persisted-key assertions.BasePersistenceStoreTest: final saved keys and settings/cache retention across repeated singleton-store configuration. Returning to earlier prefixes reuses the original cached responses without backing-store reads or puts.configureargument/call assertions from existing functional tests rather than repinning them to new internal overload calls. Existing response and payload assertions remain.docs/utilities/idempotency.md, “Using a custom key prefix,” includes self-contained annotation and functional handler examples with imports and concrete return values, plus all return-type/entry-point forms and migration boundaries.Verification
Tested against
6455f4506bb7a3c34fa197e108967d3b7a8be1dewith OpenJDK 25.0.5 and Maven 3.9.16.result-2rather than the persistedresult-1) and passes after retaining the original virtual configuration hook.-DskipTests. Service-dependent integration tests were not run.result-1; empty-prefix and original-overload calls independently replayresult-2; the two duplicates do not execute their suppliers again.The passing annotation/cache case persists
payments#70c24d88041893f7fbab4105b76fd9e1. After removing only that backing record, a functional call under another function name but the same prefix replays the annotated response from local cache. An empty-prefix call uses the independentorders.renamed#70c24d88041893f7fbab4105b76fd9e1namespace, which the original overload also reuses.Behavior boundaries
Changing a prefix does not migrate existing records. Methods or Lambda functions using the same non-empty prefix and payload intentionally share records and cached responses. Existing singleton store initialization semantics, payload hashing, expiration, and cache lifetime remain unchanged; this change does not introduce a separate concurrency/state-management redesign.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.