-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
B is not idempotent for identical requests #100
Comments
I concur. Here is a test run which tests idempotency (and fails): free-opportunities_opportunity-free-without-checkpoints_OpenBookingSimpleFlow_FacilityUseSlot.md This is only for Simple Flow, btw. Approval Flow allows a repeated B: free-opportunities_opportunity-free-without-checkpoints_OpenBookingApprovalFlow_FacilityUseSlot.md |
Noting this could be solved by storing the hash of a successful request at B, along with the successful response, and then reading that hash if an Order already exists to determine whether to return the same response, or an OrderAlreadyExistsError And that it also would need some kind of AsyncLock to avoid two Orders with the same uuid being processed at the same time |
Suggested design:
Also worth noting that idempotency could be implemented using MemoryCache in the OrderStore, or another similar method, rather than storing the hash/response in the Order table - as the response probably only needs to be cached for e.g. 15 minutes. Perhaps the ref impl should use MemoryCache rather than storing this in the DB in its example, as it’s also cleaner from a GDPR compliance perspective (personal data in the response is not stored for longer than is needed, and not duplicated)? Or perhaps the above hooks could be be virtual rather than abstract and include a default MemoryCache implementation? Would make for a cleaner upgrade path for existing implementers too. If we did this potentially the default implementation should also compress responses (e.g.) to optimise memory usage. The above hooks would support both… Also add an AsyncLock or similar to ensure that two requests for the same UUID are not processed in parallel |
I started trying to implement per the above design suggestions, but came across an issue:
So instead I looked at modifying Let me know which you would prefer, or if I've got the wrong end of the stick. Also, the above aside, I think /// <summary>
/// Result of creating (or attempting to create) an Order in a store
/// </summary>
public enum CreateOrderResult
{
OrderSuccessfullyCreated,
OrderAlreadyExists
} instead of a bool, as the above matches |
Yes sounds good - Can see the advantages of doing this at the The tradeoff is that this is more prescriptively suggesting that a separate caching layer is used, rather than e.g. using the database to store it within the same transaction. An alternative could be that |
After some thinking about the design, I've opted for doing this optionally at the This does mean that it's not as easy to store a hash of the request in the database within |
The Booking Specification states the following:
"note call to B is idempotent for the case where OrderItems match".
However this is not the case for two identical B requests. An
OrderAlreadyExistsError
error is returned.An example of the B request sent is below:
The text was updated successfully, but these errors were encountered: