Context:
My project is divided into several modules. There is a job that checkout 
subversion repository and the others that use the same physical directory 
for their workspaces to build each module.
Currently I have only one Jenkins server setup with just one executor. What 
I want to achieve is to be able to run build per commit for the whole 
project. Though I setup post-commit-hook for update job which triggers the 
rest and installed Build Blocker plugin to avoid the situation that my 
workspace will check out to new revision while the old one is still running.

That's a really huge project a simple update may take a long time and to 
build all modules we need about 30 min (it used to be 1h 30 min :) and 
because of that I discovered that from time to time my commits are 
aggregated. I've researched a little bit and discovered that when there is 
a build that is running and subversion rest method will be notified about a 
new revision from hook script it will be added to the Jenkins queue. But 
when another notification comes to Jenkins from the same svn repository, 
the server will not schedule another build of the same jab. It will be just 
ignored instead of added to queue. After all builds finishes and a new 
notification comes, Jenkins will checkout my workspace to the last revision 
and in the changes it will include two last commits (so they will be 
aggregated).

I was studding the code and was discovered that the I may fix this problem 
by removing one condition in the *scheduleInternal* method from the class:
https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/model/Queue.java

*     if(!shouldScheduleItem) {*
*        duplicatesInQueue.add(item);*
*     }*

I understand that that might be not standard behaviour for Jenkins 
(possible lack of functionality or a bug) though I would like to create my 
own custom plugin to fix this issue.
I don't want modify Jenkins core but the problem is I'm not sure where 
should I start (which extension point to choose).
I know that QueueDecisionHandler is not a good point because in my case 
shouldSchedule 
method always return true:

for(QueueDecisionHandler h : QueueDecisionHandler.all())
     if (!h.shouldSchedule(p, actions))
                return null; // veto

        return scheduleInternal(p, quietPeriod, actions);
(...)

So maybe I can influence on the decision by reverting these condition and 
starting from generating Action:

for (QueueAction action: item.getActions(QueueAction.class)) {
                shouldScheduleItem |= action.shouldSchedule(actions);
     }
     for (QueueAction action: Util.filter(actions,QueueAction.class)) {
                shouldScheduleItem |= action.shouldSchedule(item.getActions
());
     }
     if(!shouldScheduleItem) {  // this is the condition I commented to not 
to ignore incomming builds
     duplicatesInQueue.add(item);
     }

Could you please guys help me. I don't have much experience with writing 
Jenkins plugins. I just created a fork of BlameSubversion plugin with some 
customization so far (because it didn't work with subversion hooks).

Best regards
Robert

Reply via email to