Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid cross-checks

I have several jobs to run (pseudocode):

public bool IsJob1Running;
public void DoJob1(...) { IsJob1Running = true; ... ; IsJob1Running = false; }

public bool IsJob2Running;
public void DoJob2(...) { IsJob2Running = true; ... ; IsJob2Running = false; }

...

In some cases only single job can run at a time, in others - multiple can run, but others shouldn't run (should wait or refuse to start). All this at some point lead to monstrous checks like this:

if(!IsJob1Running && !IsJob2Running && !IsJob3Running ... ) { ... }

Those are suddenly appears everywhere in the software: when user click button (or even before to disable button), before starting job, even inside DoJob, etc.

I hate it. Imagine a case when new Job99 has to be added. Then everywhere in the software all checks has to be updated to include Job99 checks.

My question: is there a pattern existing to define this kind of cross-checks (relations?), which will allow to add new jobs easily, have centralized overview of all dependencies, etc.?

Edit

To give an example:

Job 1, 2, 3 can run simultaneously, but not when job 4 is running (you have to check if job 4 is running before starting 1, 2 or 3 and vise-versa). Then there are job 5, 6 and 7, only one can run, when job 5 is called from within job 1 it shouldn't be called from within job 2.

like image 268
Sinatr Avatar asked Jun 09 '16 11:06

Sinatr


1 Answers

You can implement something like the base job class:

public abstract class BaseJob 
{
    public bool IsRunning { get; private set; }

    public void Run() 
    {
        IsRunning = true;
        RunInner();
        IsRunning = false;
    }

    public abstract void RunInner();
}

and then inherit all your jobs from this:

public class LoadUserDataJob : BaseJob
{
    public override void RunInner()
    {
        // load user data
    }
}

Then, you will be able to have a list of actions over your jobs:

// Check if there is any running task
if (jobsArray.Any(j => j.IsRunning))

// Check if there is a task of type LoadUserDataJob running
// Use Where->Any instead of Single if there are many jobs of this type
if (jobsArray.Where(j => j is LoadUserDataJob).Any(j => j.IsRunning))

You can also combine this with some kind of Task and use Task.WaitAny, Task.WaitAll in order to provide waiting for execution.

Talking about an universal framework or pattern, which will automatically detect and check job dependencies, sequences and execution order, then I cannot imagine one - it strongly depends on your business logics and types of your jobs.

like image 76
Yeldar Kurmangaliyev Avatar answered Oct 01 '22 06:10

Yeldar Kurmangaliyev