Hey team, quick noob design question: Context: • At a certain time, there some some work to do. • I have a bunch of machines • Only 1 worker needs to do the work What would be the system you would design, so you "assign" the task to one of the workers? Am thinking:
Each worker tries to write "I will do it" to some database key
The one that succeeds is the designated worker
Would you do it differently?Depending on the scale of the system, I might use an actual queue rather than a DB table.
But on a DB level, update the_table set worker_id = ? where task_id = ? and worker_id is null
with my-id
and task-id
-- and then check the update count: because of the worker_id is null
clause, only one process can succeed so an update count of 1
means success and 0
means either "no work" or "someone else got it". So you can poll for work to be done with select task_id from the_table where worker_id is null order by task_id asc
(and optionally limit to one row, however your db supports that, or get all tasks ready to work on and iterate on them with that update
until you succeed or run out)
Beautiful! Thank you Sean -- this is going to be for the lil journal app, so will stick to db, but above sounds great!
If you have a task status column, you'll want to include that in the query and update as well I expect.
e.g., a status
column that has values like new, in-progress, done. Depending on whether you would ever reset worker_id
back to null
. But it would add clarity to set worker_id = ?, status = 'in-progress'
and to query for worker_id is null and status = 'new'
even if it were a bit redundant.
hey team!
okay, https://github.com/stopachka/jt/pull/2/files
^ this is a poor man's task setup. two things I'd like you take on, as well as anything else you notice ofc
• i introduced a throwable-promise
abstraction -- am not sure if this is idiomatic. would love your take : )
• would love your take on the handle-..
code. I abstract try-grab-task!
, but am aware that perhaps we can abstract even further.