kerner1000
kerner1000

Reputation: 3558

Eclipse RCP IJob: Limit numer of concurrent executing jobs

How can I tell Eclipse RCP Job management to run at most x jobs at the same time?

EDIT:

It works by using a custom scheduling rule as described in the answer.

Its important to never pass the same rule reference to more than one job.

Here is the class I use:

public class JobMaster {

private class Listener implements IJobChangeListener {

    @Override
    public void aboutToRun(final IJobChangeEvent event) {
    }

    @Override
    public void awake(final IJobChangeEvent event) {
    }

    @Override
    public void done(final IJobChangeEvent event) {
        synchronized (JobMaster.this) {
            running--;
            System.err.println("now running " + running);
        }
    }

    @Override
    public void running(final IJobChangeEvent event) {
        synchronized (JobMaster.this) {
            running++;
            System.err.println("now running " + running);
        }
    }

    @Override
    public void scheduled(final IJobChangeEvent event) {

    }

    @Override
    public void sleeping(final IJobChangeEvent event) {
    }

}

private class MyRule implements ISchedulingRule {

    public MyRule() {

    }

    @Override
    public boolean contains(final ISchedulingRule rule) {
        if (rule == this) {
            return true;
        }
        return false;

    }

    @Override
    public boolean isConflicting(final ISchedulingRule rule) {
        synchronized (JobMaster.this) {
            if (rule == this) {
                return true;
            }
            if (rule instanceof MyRule) {
                return running >= maxRun;
            }
            return false;
        }
    }
}

private final Listener l = new Listener();

private final int maxRun;

private volatile int running = 0;

public JobMaster(final int maxRun) {
    this.maxRun = maxRun;

}

public synchronized void add(final Job j) {
    j.setRule(new MyRule());
    j.addJobChangeListener(l);
    j.schedule();
}

}

Upvotes: 2

Views: 883

Answers (2)

AndreasB
AndreasB

Reputation: 329

Starting with Eclipse Mars (4.5), one can use job groups to limit the number of concurrent threads:

JobGroup jobGroup = new JobGroup("Job...", /* maxThreads*/ 10, /* seedJobsCount */ 100);

for (int ii = 0; ii < 100; ii++)
{            
    Job job = new Job("job name")
    {
        @Override
        protected IStatus run(IProgressMonitor monitor)
        {
            // do something
            return Status.OK_STATUS;
        }
    };
    job.setJobGroup(jobGroup);
    job.schedule();
}

jobGroup.join(10000, monitor);

Upvotes: 2

greg-449
greg-449

Reputation: 111198

The Job Manager does not have a way to limit the overall number of jobs.

For Jobs that you are creating you could create an ISchedulingRule rule which limited the number of your jobs that run at the same time. Call Job.setRule(rule) to set the rule on the job (do this before scheduling the job).

An example scheduling rule (from Java Debug):

class SerialPerObjectRule implements ISchedulingRule {

  private Object fObject = null;

  public SerialPerObjectRule(Object lock) {
     fObject = lock;
  }

  public boolean contains(ISchedulingRule rule) {
    return rule == this;
  }

  public boolean isConflicting(ISchedulingRule rule) {

    if (rule instanceof SerialPerObjectRule) {
      SerialPerObjectRule vup = (SerialPerObjectRule)rule;
      return fObject == vup.fObject;
    }

    return false;
  }
}

This stops more than one job that uses a particular object from running at a time.

Update:

The job manager checks the following conditions on a scheduling rule:

// contains method must be reflexive
Assert.isLegal(rule.contains(rule));

// contains method must return false when given an unknown rule
Assert.isLegal(!rule.contains(nullRule));

// isConflicting method must be reflexive
Assert.isLegal(rule.isConflicting(rule));

// isConflicting method must return false when given an unknown rule
Assert.isLegal(!rule.isConflicting(nullRule));

Upvotes: 1

Related Questions