Bug 114269 - [jobs] Customizable job scheduling priorities
Summary: [jobs] Customizable job scheduling priorities
Status: REOPENED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Runtime (show other bugs)
Version: 3.1.1   Edit
Hardware: PC Windows 2000
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: platform-runtime-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-10-28 19:01 EDT by Ian Graham CLA
Modified: 2014-04-24 11:41 EDT (History)
2 users (show)

See Also:


Attachments
JUnit Plugin test that shows effects of priority on job scheduling (2.91 KB, text/plain)
2005-10-28 19:07 EDT, Ian Graham CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ian Graham CLA 2005-10-28 19:01:28 EDT
I realize that the Job doc says "There is no guarantee that jobs of one priority 
will be run before all jobs of lower priority."  However, the reality seems to 
be that priority has no effect except for distinguishing DECORATOR from all the 
other priorities.  Unless a job has DECORATOR priority it just seems to get run 
in the sequence in which it was scheduled, and maybe that's only because of a 
minimum startup delay that gets inserted.

So I'm now going to have to do some complicated scheduling when a priority-based 
approach would have been good enough for my purposes.

Although I don't need a guarantee, something approximately in order would still 
be really useful.
Comment 1 Ian Graham CLA 2005-10-28 19:07:08 EDT
Created attachment 28967 [details]
JUnit Plugin test that shows effects of priority on job scheduling

I've attached a JUnit Plugin test that shows how little effect priority has.
Comment 2 Ian Graham CLA 2005-10-28 22:03:28 EDT
OK, I discovered that priority is entirely ignored, except for a start-delay 
tweak.  JobQueue.enqueue() uses InternalJob.compareTo() to insert into the 
queue, but compareTo() only uses startTime, ignoring priority.

For a moment I thought I could just override compareTo(), but then I discovered 
that it has been declared final.  Is this necessary?  Unfortunately, I haven't 
been able to come up with a scheduling workaround to get precisely the behaviour 
I need, so it'd be really helpful to be able to override this method.  The only 
concern I can see is that maybe compareTo() is also used in a different context 
where startTime really needs to be the deciding factor(it'd be helpful if the 
doc for InternalJob.compareTo() described the context for which it is intended).

Comment 3 John Arthorne CLA 2005-10-31 11:49:19 EST
Hi Ian, 

Everything you say is true.  The scheduling priority is used to tweak the
startTime field, and then jobs are sorted in the wait queue by start time.  This
has similar behaviour to the decaying properties in traditional Unix scheduling.
 Priority essentially increases the longer the job is in the queue. A job of
lower priority that has been in the queue awhile may run before a high priority
job that has just arrived in the queue.

I don't think it is appropriate for jobs to be able to completely control their
scheduling priority, either via overriding compareTo or through other means.
Everyone probably thinks *their* job is more important than other jobs and
should always run first ;)
Comment 4 Ian Graham CLA 2005-10-31 14:46:26 EST
In my case we're talking about an RCP app, and within a limited context I only 
care to influence the scheduling of my own jobs relative to each other, with 
greater emphasis on priority.  In fact, for my jobs I really really don't want 
time in the queue to have the effect of increasing priority, at least not 
relative to each other.

So I can see how having InternalJob.compareTo() marked final is beneficial for 
the IDE, to keep rogue plugins in line.  But it does impact the flexibility I 
could have for my RCP app.

How about figuring out a way to allow jobs within the same family to have more 
explicit control over scheduling with respect to other family members?  Maybe an 
overrideable compareFamilyMemberTo() that gets used by compareTo() if they are 
the same family member, and for which the default implementation is identical to 
the current compareTo().  That would provide RCP apps with more flexibility 
without allowing IDE plugins to create aggressive rogue Jobs too easily.
Comment 5 John Arthorne CLA 2006-10-27 16:25:13 EDT
Not planning to implement this.
Comment 6 Ian Graham CLA 2006-10-30 09:54:43 EST
(In reply to comment #5)
> Not planning to implement this.
> 

John,

I really like Jobs and their well-separated UI support.

And I do recognize that my specialized - and admittedly now somewhat neglected - RCP app really calls for a custom scheduler rather than tweaks to Jobs.  It's been a while since I've looked at it all, but I remember that it didn't seem viable to replace the scheduler.  So to take the app any further I would need a completely separate scheduler/task framework to get the control I needed, or add my own layer on top of the existing job framework that does a lot of canceling and rescheduling of jobs.

However, I thought that my last suggestion above would have allowed me to use the existing framework directly without exposing the platform unduly to rogue Jobs that would simply try to jump the queue.  I'd get what I want: the ability to change priorities and RELATIVE execution order of MY OWN queued jobs, and rogue jobs could not generally take priority from those of other plugins.  And the implementation changes would be simple.

As an example, imagine a user scrolling right in Google maps.  Tiles that had been but are no longer visible and were already queued to be rendered could remain queued but their priority dropped so that the rendering of newly exposed and queued tiles would occur first.  Because the original tiles remained queued, the user may subsequently scroll back left again and find the tiles already rendered, even though they hadn't been before the user had scrolled away from them.

It'd be nice and easy just to change priorities of tile-rendering jobs as the visible portion of the map is moved.

Could one get the required effect by canceling jobs and rescheduling them immediately with a lower priority?  Would that be a cleaner solution than my suggestion in comment #4, or is it just a matter of needing someone to do the work when there are so many higher priority things to be done?
Comment 7 John Arthorne CLA 2006-10-30 10:04:19 EST
Reopening.
Comment 8 John Arthorne CLA 2006-10-30 10:16:34 EST
I'm going to mark this LATER rather than WONTFIX. I think you can achieve the kind of result you're looking for by layering something on top.  For example you can manage a queue of work items in whatever way you want, and then allocate a job or two to process items from that queue.  This gives you ultimate control over the work your plugin is doing without affecting the overall job execution queue. A number of components do this already.  The open question is whether this can or should be generalized in a way that suits a wide variety of clients.  I suspect we could do something useful here, but it doesn't fit into the current 3.3 plan.

As an interesting aside, I've spoken with members of the Maestro team at NASA who are using the jobs framework for exactly the purpose you describe... tile-rendering very large images in parallel with multiple jobs (http://www.eclipse.org/community/casestudies/NASAfinal.pdf).
Comment 9 John Arthorne CLA 2009-08-18 16:15:30 EDT
[LATER->WONTFIX] The "LATER" bugzilla resolution is being removed so reopening to mark as WONTFIX.
Comment 10 John Arthorne CLA 2009-08-18 16:21:27 EDT
[LATER->WONTFIX] The "LATER" bugzilla resolution is being removed so reopening to mark as WONTFIX.
Comment 11 Mickael Istria CLA 2014-04-24 11:41:31 EDT
I'd like to reopen this issue.
I have a use-case where I create around 30 jobs polling p2 repo, that are currently running with a single thread but that's a detail, and I know that some of them are more important than others and that the output of the job is most likely going to be necessary earlier.
My jobs typically have a Job.LONG priority, and I want to set some of those jobs to (Job.LONG - 1) in order to make them run before the other job I created.
But the API doesn't allow that, so that I have to make my "most likely useful jobs" using priority Long.SHORT, which would have more import on other 3rd-party jobs than using Job.LONG - 1.