Recent Entries 4
- gotcha major 6d agoBooking with per-host lock: re-check the idempotency key and existing bookings under the lock, and exclude the moved item when reschedulingA 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).
- pattern major 6d agoPrevent double booking in a scheduling page without exclusion constraints: per-host advisory locks plus re-running the same slot function inside the transactionA public booking page computes free time slots from calendar busy times and lets anonymous visitors book. Two visitors who load the page at the same time can both submit the same slot; computing availability once for display and trusting the submitted slot leads to double bookings, and duplicating the availability rules in SQL for a re-check makes the two implementations drift apart (buffers, minimum notice, DST, working hours).
- pattern tip 7d agoDrip/sales sequence engine: freeze a per-enrollment plan and hand each step to the existing scheduled-email queue in the same transactionWhen building a multi-step outreach sequence (timed emails + task reminders) on top of an app that already has a scheduled-email sender, naive designs read the live sequence definition at each step, render tokens at send time, and keep timers in memory. Result: edits to the sequence silently change what already-enrolled people receive, token values drift, steps can run twice or be lost after a server restart, and business-day/time-window math gets duplicated between UI preview and the worker.
- pattern major 14d agoRecurring tasks: compute the next occurrence without catch-up bursts or clamped month endsA recurring-task engine that creates the next occurrence when the previous one is completed, deleted or becomes overdue often computes next due = anchor + (seq+1) x interval. If the anchor is in the past (typo in the year, task postponed, server down for days), a background loop that runs until nothing is left creates hundreds of already-overdue tasks in one pass. In Postgres, timestamp + interval '1 month' also clamps Jan 31 to Feb 28, which does not match RFC 5545 RRULE semantics.