-
Notifications
You must be signed in to change notification settings - Fork 60
Cache zoneId parsing to avoid repeated timezone resolution
#425
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
base: master
Are you sure you want to change the base?
Conversation
The getZoneId() method was parsing the timezone string on every call using ZoneId.of(), which is expensive and includes exception handling. This method is called frequently from ScheduleBuildAction, causing unnecessary performance overhead.
MarkEWaite
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.
I think this may invalidate the cache even when the same value is being assigned as was already there. It seems that it should retain the cache in that case.
src/main/java/org/jenkinsci/plugins/schedulebuild/ScheduleBuildGlobalConfiguration.java
Show resolved
Hide resolved
|
The change seemed/seems logical to me, but Claude says differently (whether true or false???): WDYT? |
Claude Code correctly identifies a race condition that might happen and
describes it like this:
The problem is in the getZoneId() method at lines 146-147
and 149-150. When setting the cache, both cachedZoneId and
cachedTimeZoneString are updated, but these are separate operations that
aren't atomic. In a multi-threaded environment:
1. Thread A calls setTimeZone("America/New_York")
2. Thread B calls getZoneId() and sees the cache is invalid
3. Thread B sets cachedZoneId = ZoneId.of("America/New_York")
4. Thread A clears the cache (sets both to null)
5. Thread B sets cachedTimeZoneString = "America/New_York"
Now we have an inconsistent state where cachedZoneId is null but
cachedTimeZoneString is not null.
This reverts commit 6a6c7cb.
I don't see how the new code is different from the old code in the scenario described by Claude Code. At the completion of step 3, cachedZoneID is non-null and cachedTimeZoneString is null. At the completion of step 4, both are null. At the completion of step 5, cachedTimeZoneString is non-null and cachedZoneID is null, whether or not the conditional is included to not clear the cache. |
|
Because I'm not as confident in reasoning about threading as I would like to be, I reverted the change. 551c63e |
… forcing) an invalid value. Adding in protection, even though it's probably not really needed.
mawinter69
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.
We could also convert the timeZone field to ZoneId as ZoneId is serializable. Would require to add java.time.ZoneRegion to META-INF/hudson.remoting.ClassFilter (while it is not generally allowed in core). The methods setTimeZone and getTimeZone would keep their signature but need to do the conversion from/to String as Stapler is not able to handle to convert a String to a ZoneId. There would be no need for any conversion in the load method or the like.
I think this is much cleaner than adding caching here.
| } else { | ||
| return FormValidation.error(Messages.ScheduleBuildGlobalConfiguration_TimeZoneError()); | ||
|
|
||
| // Check for null, empty, or whitespace-only values |
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.
Do we really need that extended checking? This is a dropdown filled from the doFillTimeZoneItems method. So unless someone modifies the html this should always be a valid timezone and never be null, empty or whitespace only I think.
The getZoneId() method was parsing the timezone string on every call using ZoneId.of(), which is expensive and includes exception handling. This method is called frequently from ScheduleBuildAction, causing unnecessary performance overhead.
Testing done
mvn clean verifySubmitter checklist