3

We have a job table that triggers a notification when a new job gets inserted. Clients that can handle such jobs may subscribe to those notifications. When a client receives a notification, he can "lock" the job, so no other client will try to process it. We have also take care of errors and if a job takes to long to process.

Problem: A client can only handle X jobs at the same time. On heavy load, all clients are busy handling their jobs. And new jobs may not get handled right away. If the client is no longer busy, he may query the table to find jobs that have not been processed yet. But if all clients stay busy for a long time (they finish jobs but new jobs arrive at the same time), those old jobs will never be processed.

Idea: After a client has processed Y jobs, he ignores all new jobs, and queries the table for the old ones. But I am not really comfortable with that idea.

Any ideas by you? If you need more information don't hesitate to ask for them.

2

This is the problem closely related to the job scheduling. But there are two issues you have to consider:

1) Your clients are free to choose any job they want. They know when new jobs arrive and can pick any one they want. If you really want to control what they do you should really limit what they can know and reserve for processing.

2) Before really delving deeper into the details and implementations of how all the scheduling and querying should work, you should first answer the next questions:

  • What do I want from my system's scheduling - determinism, fairness or efficiency of use?
  • Do I want my jobs to be handled the sooner the better?
  • Or I want to handle new jobs before old?
  • Or old before new?
  • Or there is some other property of jobs(estimated duration, tag) that should determine their scheduling?
  • Can I preemptively stop(pause, abort) the job to handle a new one(not your case, but nonetheless)?
  • And other similar questions...

As I understand for now you want:

To handle the new jobs as soon as possible, but never allow the old jobs to be unprocessed.

The simplest solution is FIFO-like processing with one job producer, but multiple job handlers.

I can suggest you something like:

// Job - the data needed to process the job
public interface IJob {...}

// Client - client that handles the jobs - IJobScheduler can suggest JobClient to 
// requery for a new job if needed.
public interface IJobClient
{
    void SuggestQueryForNextJob();
}     

// Each JobClient has its own JobQuery(IJobScheduler knows what to show to each of it).                    
// JobClient can query the next job or notify about the current one.
public interface IJobQueue
{
   bool TryQueryNextJob(ref IJob nextJob); 
   void NotifyAboutJob(JobCompletionState jobCompState)
}

// Your main server, that allows JobConsumers to register themselves for job handling
public interface IJobScheduler
{
    IJobQueue RegisterConsumer(IJobConsumer consumer);     
}

This scheme will concentrate all the scheduling on your JobProducer's side, actually allowing for nearly any possible scheduling mode.

It will demand its fair share of proxies and other stuff, but will greatly simplify your JobClients.

2

If I understand your question correctly, I think the following approach should work:

If a client ignores a notification once, because of its load, it ignores all following notifications too (even if the load decreases). From then on, it relies only on querying the database for old requests. Once all old requests are handled, it will start accepting notifications again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.