Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
As I explained in #1001,
findNextDispatchFrames
returns the exact same frames in the exact same order when multiple threads or multiple Cuebot machines calls it at the same time. Only one caller offindNextDispatchFrames
will succeed to dispatch the frames, the all other threads and machines fail with this error message.It is wasting CPU, PostgreSQL transaction, and time.
Solution
Introduce
b_scheduled
boolean andts_scheduled
timestamp to Frame table.Cuebot updates
b_scheduled
when it dispatches the frames.So the other threads can filter out
b_scheduled=true
frames for their dispatch.(The original idea, adding a new frame state involves more logic change, database functions, etc. gave up)
Implementation
The original
findNextDispatchFrames
SQL isSELECT
.This PR will change it to
UPDATE
for updatingb_scheduled
andts_scheduled
.But at the same time it will also append
RETURNING
clause to fetch the updated frames.Thus the functionality will remain the same (1 atomic transaction, it will return the exact same frames in the exact same order by the
WHERE
,ORDER BY
, andLIMIT
. The exception is that it won't returnb_scheduled=true
frame), but be capable to updateb_scheduled
andts_scheduled
.ts_scheduled
is for a fail-safe logic. Cuebot may crash afterb_scheduled
update and then the frame will be stranded. The solution is that Cuebot will usets_scheduled
timestamp as timeout to reschedule the frame again.ScheduledDispatchFrames
is a convenient class which implementsAutoCloseable
andIterable
to easily ensure resettingb_scheduled
tofalse
(unschedule
) when the thread didn't dispatch the scheduled frames.Summary
findNextDispatchFrames
→scheduledNextDispatchFrames
FIND_DISPATCH_FRAME
SELECT queries →SCHEDULE_DISPATCH_FRAME
UPDATE queries with RETURNINGList<DispatchFrame> frames = findNextDispatchFrames
→try (ScheduledDispatchFrames frames = scheduleNextDispatchFrames)