Break it down into pieces:
You have a job description - which may have some constraints on where its performed - and you have a queue of jobs to be performed, broadly speaking if there are no other constraints you'd expect the jobs to be done in order i.e. you take them from the front of the queue and add them to the end.
If we run the queue as a single table then jobs will have 3 states:
- Not Started
- In Progress
- Completed
So looking for work to do is simply a matter of finding the first job (or the first n jobs if work is to be assigned in a batch) that are not started and then flagging them as started. If the constraints are more complex than simply the first n available jobs then it becomes the first n available jobs that meet the constraints, but it should still be fairly simple.
That implies the following fields in the queue table:
- Status
- DateQueued (date and time) for sort
- DateStarted (date and time) for timeout
- AssignedTo
One should probably add a DateCompleted - but if the work is batched that's not going to be strictly accurate (it'll be time reported as complete).
So for a worker (the worker "app") the process becomes:
- Connect to server
- Report completed work - set status and completion time
- Request new work
- Search for new work for worker (first n jobs not started that worker can do)
- Assign new work to worker (set status, Date Started and assigned to) - search and assign as a transaction.
- List work and disconnect
Separately you'd need processes to queue work, to look for jobs that have "timed out" so that the status can be reset and to archive or otherwise clear out completed jobs from the queue.
Full table would have the following plus any audit fields required.
- ID
- JobID -- Assuming that jobs are defined elsewhere
- StatusID
- DateQueued
- DateStarted
- AssignedToID
- DateCompleted
Hope that helps...