-
Notifications
You must be signed in to change notification settings - Fork 80
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
Using own executor service #61
Conversation
Any thoughts about this? |
@ingwarsw |
if (executorService == null) { | ||
// corePoolSize is set to 10, but will only be created if needed. | ||
// ScheduledThreadPoolExecutor "acts as a fixed-sized pool using corePoolSize threads" | ||
executorService = new ScheduledThreadPoolExecutor(10, new NamingThreadFactory(new DaemonThreadFactory(), "SCMEvent")); |
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.
Note that Timer
is also wrapped in utilities to
- impersonate
ACL.SYSTEM
- handle errors, if we are not using
SafeTimerTask
- maintain the
Thread.contextClassLoader
Whether any of those issues are important for this usage, I have no idea offhand. But perhaps Timer
should get a utility factory
public static ScheduledExecutorService newService(String name, int corePoolSize) {
return new ImpersonatingScheduledExecutorService(new ErrorLoggingScheduledThreadPoolExecutor(corePoolSize, new NamingThreadFactory(new ClassLoaderSanityThreadFactory(new DaemonThreadFactory()), name)), ACL.SYSTEM);
}
for easy reuse.
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 one does everything except logging errors if we are not using SafeTimerTask
I can use exactly the same as in timer... but I choose to use that one for some purpose..
It was so long ago I dont even remember why..
But I remember it was not accident..
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.
And Timer
is in core so I cannot change it from here..
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 one does everything except logging errors
It does not do the impersonation or context class loader maintenance.
Timer
is in core so I cannot change it from here
Of course, but we can have a core PR, and via JEP-305 it is even straightforward to have an on-hold
PR in the plugin which verifies its usage.
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.
I see that there was change in Timer.. ok.. so it does more now..
So it would be great to move it somewhere in one place..
And maybe it would be easier and better to just allow changing size of timer pool via variable or something?
Here https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/jenkins/util/Timer.java#L47
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.
they sometimes takes hours to complete
A thread dump would be the background we need to analyze why.
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.
I can get thread dump.. just need to wait for busy day..
But all waits here https://github.com/kohsuke/github-api/blob/master/src/main/java/org/kohsuke/github/RateLimitHandler.java#L39
We are just got rate limit badly..
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.
And while we dont have problems with waiting for GH..
We have problem that nothing else (that relies on Timer
) on jenkins is working..
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.
Need the thread dump to see what caller is to blame.
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.
Webhook processing is going into this pool..
And there is issue with GH processing itself (sometimes rate limiting is not resetting)..
But not that easy to grasp..
And would be best to fix somewhere here..
https://github.com/kohsuke/github-api/blob/master/src/main/java/org/kohsuke/github/GitHub.java#L316
Once for good :)
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.
Ahhh it’s the rate limit back-off in the event handling. Yes event handling needs it’s own pool. I’ll take a look at this PR later, but in principle the request is sound.
Guys I can update it to looks exactly like in |
Go for the core version bump. Seems entirely reasonable to bump to that LTS at this time. Because of the core version bump, also bump the plugin’s minor version and reset patch to 0 |
@stephenc Done.. |
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.
- Minor formatting
- We should be a good citizen in the servlet spec (even if most users just kill the servlet container, it will affect downstream plugin testing as the thread pool will retain resources and more critically it will prevent the loaded classes from being unloaded and represent a memory leak when running the tests)
import java.util.concurrent.atomic.AtomicLong; | ||
import java.util.concurrent.locks.Condition; | ||
import java.util.concurrent.locks.Lock; | ||
import java.util.concurrent.locks.ReentrantLock; | ||
import javax.servlet.http.HttpServletRequest; | ||
import jenkins.util.Timer; | ||
|
||
import hudson.util.ClassLoaderSanityThreadFactory; |
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.
all imports in a-z order, no blank lines please
// ScheduledThreadPoolExecutor "acts as a fixed-sized pool using corePoolSize threads" | ||
executorService = new ImpersonatingScheduledExecutorService(new ScheduledThreadPoolExecutor(10, new NamingThreadFactory(new ClassLoaderSanityThreadFactory(new DaemonThreadFactory()), "SCMEvent")), ACL.SYSTEM); | ||
} | ||
return executorService; | ||
} | ||
|
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.
we'll need a @Terminator
annotated static method that shuts down this pool to play nicely with servlet containers that get reused, e.g. if anyone is in a downstream plugin and has lots of event unit tests, they may end up with lots of these thread pools. Better to expressly shut them down with the Jenkins lifecycle.
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.
Clicked wrong button... 2 changes per previous comment
@stephenc |
* Shutdown the timer and throw it away. | ||
*/ | ||
@Terminator | ||
public synchronized void closeExecutorService() { |
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.
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.
Actually I didnt think about it..
And I removed static because Im not sure if @Terminator
can work on static method..
But if works we should add that static back to be on safe side..
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.
I see even @stephenc mentioned it should be static..
I will create fast fixing PR..
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.
<changelist>-SNAPSHOT</changelist> | ||
<jenkins.version>2.60.3</jenkins.version> | ||
<jenkins.version>2.164.3</jenkins.version> |
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.
FWIW usually preferable to update to the oldest LTS line that has whatever core API you need. Especially in this case, because the plugin is an API intended to be used by other plugins, requiring the second-newest LTS release means that any plugin that wants to pick up the latest version of this plugin (for example jenkinsci/workflow-cps-global-lib-plugin#68) also requires that release, which is a bit prohibitive.
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.
In this case 2.107.3
was the minimum required baseline as far as I know.
In our company we have Jenkins with ~ 1000 repos in GitHub.
Most of them have a lot of tags (> 1k is standard, moved from old SCMs, but we cannot remove them so far)
Because of that processing events can take a loot of time, and Timer pool is really often all being used for event, which turns our jenkins into vegetable.