From a34cbbe37b6f1f9bf3fc749e7e026983e316482d Mon Sep 17 00:00:00 2001 From: Cameron Reeves Date: Fri, 9 Oct 2026 13:18:20 +1100 Subject: [PATCH] fix(place/room_booking_approval): answer approvals at once accept_event, decline_event and the recurring variants ended with refresh_bookings, whose last expression was the Tasker task from schedule.in. The driver executor waits on any returned value that responds to get, so every approval exec blocked for the whole refresh_debounce_seconds window (10 s by default) before replying. Concierge gives an exec 10 s, so approving a booking raced the timeout and usually looked like nothing happened even though the calendar had accepted the event. Give refresh_bookings a Nil return type so the exec replies as soon as the calendar call is queued. The spec now checks the exec answers well inside the debounce window. --- drivers/place/room_booking_approval.cr | 4 +++- drivers/place/room_booking_approval_spec.cr | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/place/room_booking_approval.cr b/drivers/place/room_booking_approval.cr index 617b8693256..daad3a20397 100644 --- a/drivers/place/room_booking_approval.cr +++ b/drivers/place/room_booking_approval.cr @@ -153,7 +153,9 @@ class Place::RoomBookingApproval < PlaceOS::Driver # Multiple calls within the 10-second window are batched into a # single poll_events call per affected system, giving the calendar # provider time to propagate the status change. - protected def refresh_bookings(system_ids : Array(String)) + # The exec runtime waits on any returned task, so this must not return + # the scheduled one. + protected def refresh_bookings(system_ids : Array(String)) : Nil return if @disable_refresh_bookings @pending_refresh.concat(system_ids) return if @refresh_scheduled diff --git a/drivers/place/room_booking_approval_spec.cr b/drivers/place/room_booking_approval_spec.cr index 23e295a3b3f..c9edce04833 100644 --- a/drivers/place/room_booking_approval_spec.cr +++ b/drivers/place/room_booking_approval_spec.cr @@ -314,15 +314,20 @@ DriverSpecs.mock_driver "Place::RoomBookingApproval" do poll_before = system(:Bookings_1)[:poll_events_calls].as_i + # The exec must respond before the debounce fires, not wait for it. + started = Time.monotonic exec(:accept_event, calendar_id: "room5@example.com", event_id: "tentative-event-1", ).get + (Time.monotonic - started).should be < 5.seconds + started = Time.monotonic exec(:decline_event, calendar_id: "room5@example.com", event_id: "tentative-event-4", ).get + (Time.monotonic - started).should be < 5.seconds sleep 11