Module: OneMoreTime
- Defined in:
- lib/one_more_time.rb,
lib/one_more_time/version.rb,
lib/one_more_time/idempotent_request.rb
Defined Under Namespace
Classes: Error, IdempotentRequest, RequestInProgressError, RequestMismatchError
Constant Summary collapse
- VERSION =
'0.1.0'
Class Method Summary collapse
Class Method Details
.start_request!(idempotency_key:, request_path: nil, request_body: nil) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/one_more_time.rb', line 12 def start_request!(idempotency_key:, request_path: nil, request_body: nil) IdempotentRequest.create!( idempotency_key: idempotency_key, locked_at: Time.current, request_path: request_path, request_body: request_body, ) rescue ActiveRecord::RecordNotUnique # Our UNIQUE constraint was violated, so a request with the given idempotency # key already exists. Use the highest transaction isolation level to atomically # load that request record and mark it as "locked". # Similar to Rails create_or_find_by, the race condition here is if another # client deleted the request record exactly at this point. For this specific # model there is basically no risk of that happening. serializable_transaction do existing_request = IdempotentRequest.find_by(idempotency_key: idempotency_key, locked_at: nil) validate_incoming_request!(existing_request, request_path, request_body) existing_request.update!(locked_at: Time.current) unless existing_request.finished? existing_request end end |