-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
[JENKINS-47517] Revert the change to the default behavior of Queue.Task.getCauseOfBlockage #3099
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JENKINS-47517] Revert the change to the default behavior of Queue.Task.getCauseOfBlockage #3099
Conversation
…sk.getCauseOfBlockage.
|
This pull request originates from a CloudBees employee. At CloudBees, we require that all pull requests be reviewed by other CloudBees employees before we seek to have the change accepted. If you want to learn more about our process please see this explanation. |
svanoort
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's subtle... and nasty. Good catch.
|
@jglick any suggestion how to avoid such bugs in future? maybe there is some way to grep through all related plugins? |
|
@oleg-nenashev asked if Another solution is of course to patch
Ultimately there should be some process running
It is definitely possible to find usages of an API whose behavior you are proposing to change, deprecate, etc., as in this example. Somewhere (where?) there is also an index of core APIs using actual code analysis, rather than plain-text search. We used to have Sourcerer running on Jenkins but this has been broken for a long time. |
|
@oleg-nenashev also asks whether we could have the equivalent of |
FWIW I usually adapt https://github.com/jenkins-infra/deprecated-usage-in-plugins to find what I'm looking for, e.g. jenkins-infra/usage-in-plugins#7. Signatures can be hard-coded in |
So the only way I can see to do that would be to use a
We could go even more fancy to see if there are nested calls... but that would have a bigger impact on the expected cost of the method. |
|
Yes it is possible to break cycles using |
|
Would be nice to have a test in core to make sure we don't regress this again. |
|
@jglick I introduced it because if someone did not override CauseOfBlockage causeOfBlockage = task.getCauseOfBlockage();
if (causeOfBlockage != null) { // here we need to check `task.isBlocked`
return task.getCauseOfBlockage();
if (!canRun(task.getResourceList())) {
...
} Now I think it was better to add a check for |
|
Having both methods seems like a bad design in the first place. Maybe we can simply deprecate |
…ge, which you needed to implement anyway.
Materially changed since review.
| * A project must be blocked if its own previous build is in progress, | ||
| * or if the blockBuildWhenUpstreamBuilding option is true and an upstream | ||
| * project is building, but derived classes can also check other conditions. | ||
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now no-op overrides.
| * | ||
| * <p> | ||
| * Short-hand for {@code getCauseOfBlockageForItem()!=null}. | ||
| * @deprecated Use {@link #getCauseOfBlockage} != null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As of 2.85 was already not being called by core, so why keep it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be also restricted?
| */ | ||
| @Deprecated | ||
| String getWhyBlocked(); | ||
| default String getWhyBlocked() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some other methods in this interface could benefit from default implementations but I will leave that to another day.
| */ | ||
| @CheckForNull | ||
| default CauseOfBlockage getCauseOfBlockage() { | ||
| if (isBuildBlocked()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fix.
| @Test | ||
| public void causeOfBlockageOverrides() { | ||
| Queue.Task t = new LegacyTask(); | ||
| assertFalse(t.isBuildBlocked()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With Queue.java reverted to master version, reproduces the StackOverflowError.
| assertNull(t.getWhyBlocked()); | ||
| assertNull(t.getCauseOfBlockage()); | ||
| } | ||
| static class LegacyTask extends AbstractQueueTask { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same essential structure as current org.jenkinsci.plugins.workflow.job.AfterRestartTask.
| @Override public int hashCode() { | ||
| return cnt.hashCode(); | ||
| } | ||
| @Override public boolean isBuildBlocked() {return isBlocked;} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was only a test task. A real one would already have needed to implement getCauseOfBlockage to provide a message to the user. (It was abstract prior to #2879 in 2.62 so it is unlikely that new code was written against 2.62–2.85 that assumed that only implementing isBuildBlocked was OK.)
| queue.maintain(); | ||
|
|
||
| assertEquals(1, r.jenkins.getQueue().getBlockedItems().size()); | ||
| CauseOfBlockage actual = r.jenkins.getQueue().getBlockedItems().get(0).getCauseOfBlockage(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing something which is no longer wanted.
oleg-nenashev
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐝 Maybe needs some polishing later, but it seems to be a good fix for now
| * | ||
| * <p> | ||
| * Short-hand for {@code getCauseOfBlockageForItem()!=null}. | ||
| * @deprecated Use {@link #getCauseOfBlockage} != null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be also restricted?
|
I assume @Jimilian also approved it, am I right? |
|
@oleg-nenashev, yes, fix itself looks fine for me. But I'm not 100% sure that it handles mentioned problem when p.s. Maybe I still do not get classpath/api magic in Jenkins. |
No. Why? |
No, it does not. Already discussed above in #3099 (comment). I do not consider it a problem. |
|
I think adding a new type of restriction, |
At the cost of interrupting unrelated developer workflows, such as Anyway I see no reason why avoidance of this method needs to be accelerated beyond any other deprecated API.
It can be, yes, but that is a separate issue, solvable using standard techniques such as compiler flags, or the Warnings plugin for Jenkins for that matter. |
|
@reviewbybees done |
|
Merging this to make sure it gets into 2.86 since I think the |
|
Thanks @jglick ! |
See JENKINS-47517. Reverts an inessential-seeming, and extremely incompatible, part of #3038.
Proposed changelog entries
StackOverflowErrorthrown under some conditions when using Pipeline on 2.85.@reviewbybees @jenkinsci/code-reviewers