fix(hotreload): Unset INSTANCE of executor on shutdown#324
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR fixes issue #315 by ensuring the singleton INSTANCE of the scheduled executor is properly reset to null during shutdown, preventing stale references during hot reload scenarios.
Key changes:
- Modified the
setIntervalmethod to return void instead of ScheduledFuture across all implementations - Added proper INSTANCE cleanup in shutdown methods to support hot reload scenarios
- Enhanced logging for better debugging of executor lifecycle events
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| UnleashScheduledExecutor.java | Updated interface to change setInterval return type and added shutdownNow method |
| UnleashScheduledExecutorImpl.java | Implemented INSTANCE cleanup in shutdown methods and added logging |
| SynchronousTestExecutor.java | Updated test implementation to match new interface signature |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| public void shutdown() { | ||
| this.scheduledThreadPoolExecutor.shutdown(); | ||
| INSTANCE = null; | ||
| LOG.info("Shutdown - Scheduled Executor"); | ||
| } | ||
|
|
||
| @Override | ||
| public void shutdownNow() { |
There was a problem hiding this comment.
Setting INSTANCE to null in shutdown methods creates a race condition. If another thread calls getInstance() while shutdown is executing, it could create a new instance of an executor that's being shut down. Consider using proper synchronization or marking the instance as shutting down before nullifying it.
| public void shutdown() { | |
| this.scheduledThreadPoolExecutor.shutdown(); | |
| INSTANCE = null; | |
| LOG.info("Shutdown - Scheduled Executor"); | |
| } | |
| @Override | |
| public void shutdownNow() { | |
| public synchronized void shutdown() { | |
| this.scheduledThreadPoolExecutor.shutdown(); | |
| INSTANCE = null; | |
| LOG.info("Shutdown - Scheduled Executor"); | |
| } | |
| @Override | |
| public synchronized void shutdownNow() { |
| public void shutdown() { | ||
| this.scheduledThreadPoolExecutor.shutdown(); | ||
| INSTANCE = null; | ||
| LOG.info("Shutdown - Scheduled Executor"); | ||
| } | ||
|
|
||
| @Override | ||
| public void shutdownNow() { |
There was a problem hiding this comment.
Setting INSTANCE to null in shutdown methods creates a race condition. If another thread calls getInstance() while shutdown is executing, it could create a new instance of an executor that's being shut down. Consider using proper synchronization or marking the instance as shutting down before nullifying it.
| public void shutdown() { | |
| this.scheduledThreadPoolExecutor.shutdown(); | |
| INSTANCE = null; | |
| LOG.info("Shutdown - Scheduled Executor"); | |
| } | |
| @Override | |
| public void shutdownNow() { | |
| public synchronized void shutdown() { | |
| this.scheduledThreadPoolExecutor.shutdown(); | |
| INSTANCE = null; | |
| LOG.info("Shutdown - Scheduled Executor"); | |
| } | |
| @Override | |
| public synchronized void shutdownNow() { |
There was a problem hiding this comment.
I think this makes sense
Pull Request Test Coverage Report for Build 17575487826Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
gastonfournier
left a comment
There was a problem hiding this comment.
I think this can work. I've added a small suggestion inline with Copilot suggestion: #325
|
|
||
| public static synchronized UnleashScheduledExecutorImpl getInstance() { | ||
| if (INSTANCE == null) { | ||
| LOG.info("INSTANCE was null, rebuilding Scheduled Executor"); |
There was a problem hiding this comment.
Should this be debug?
There was a problem hiding this comment.
It shouldn't be here at all. I'll remove it before merging
| private final ExecutorService executorService; | ||
|
|
||
| public UnleashScheduledExecutorImpl() { | ||
| LOG.info("Creating Scheduled executor"); |
There was a problem hiding this comment.
Should this be debug? or be removed altogether
There was a problem hiding this comment.
Same, shouldn't be here. Added to verify behaviour during testing in example.
fixes #315