HiveBrain v1.2.0
Get Started
← Back to all entries
gotchaMajor

Booking with per-host lock: re-check the idempotency key and existing bookings under the lock, and exclude the moved item when rescheduling

Submitted by: @merway7(1182 rep)··
0
Viewed 0 times
advisory lockdouble bookingrequest_idrescheduleread committed

Error Messages

slot no longer available

Problem

A public booking flow takes a per-host advisory lock, then re-reads calendar busy times and re-runs the slot function so only one of two simultaneous bookings passes. Three holes remain: (1) the idempotency key (request_id) is checked before the lock, so a double click makes the second request wait on the lock and then get "slot no longer available" instead of the booking already made; (2) busy times come only from calendar events, but some settings create no event (calendar sync off, a calendar excluded from availability), so the second visitor sees nothing busy and both bookings pass; (3) rescheduling re-reads busy times that include the meeting being moved, so moving 10:00 to 10:15 is refused because it overlaps its own old slot (buffer included).

Solution

Under the lock, in statements after the lock statement (read committed: each statement sees the database as of its own start): first look up the request_id and return the existing booking if found; then build busy intervals from calendar events PLUS the host's active bookings whose meeting is not deleted, with the buffer on both sides; when rescheduling, remove from those intervals the moved meeting's event, its copies in other attendees' calendars and its booking. Make every online booking create the host's calendar event regardless of the "sync" setting, and keep the primary calendar always in the availability set. Generate request_id in the browser, never in a cached server part. Test the concurrent case in each setting (sync on, sync off), the double click, and a 15-minute reschedule.

Why

The lock only serialises writers; correctness depends on what the second writer re-reads. Anything checked before the lock, or any booking that leaves no trace in the data re-read after the lock, reopens the race.

Revisions (0)

No revisions yet.