Skip to content

Conversation

@xichen01
Copy link
Contributor

@xichen01 xichen01 commented Jan 6, 2026

What changes were proposed in this pull request?

Context

If a BackgroundService task takes longer than the interval, the next task will be executed immediately after the previous task completes.
For previous discussion #9185
Current PR Fix BackgroundService to make it follow scheduleWithFixedDelay mantics.

Implementation:

Moving future.join(); from BackgroundService#PeriodicalTask#run to after task submission, and using future.join(); to wait for all submitted tasks to complete, effectively transforms PeriodicalTask#run into a blocking function. This enables it to execute according to the scheduleWithFixedDelay pattern.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-14236

How was this patch tested?

unit test.

@ivandika3 ivandika3 added the s3-lifecycle HDDS-8342 label Jan 7, 2026
@ivandika3 ivandika3 changed the title HDDS-14236. Fix BackgroundService to follow scheduleWithFixedDelay mantics HDDS-14236. Fix BackgroundService to follow scheduleWithFixedDelay semantics Jan 7, 2026
@ChenSammi ChenSammi removed the s3-lifecycle HDDS-8342 label Jan 7, 2026
LOG.info("Starting service {} with interval {} {}", serviceName,
interval, unit.name().toLowerCase());
exec.scheduleWithFixedDelay(service, 0, interval, unit);
scheduler.scheduleWithFixedDelay(service, 0, interval, unit);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xichen01 , thanks for continue this improvement task.

Can we keep using the exec here? What's the extra benefit of introducing scheduler?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PeriodicalTask#run is now a blocking method. If exec only has one thread, when the PeriodicalTask#run blocks, Then the task submitted to the queue will remain without a thread to execute it.

Therefore, we introduce a separate thread scheduler responsible for submitting tasks, while exec is only responsible for executing the tasks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

”exec“ is a ScheduledExecutorService thread pool with no upper thread limit. I also just found it during the discussion of your last proposal patch's review.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but the queue of ScheduledExecutorService will always not be full, so only corePoolSize thread will work.


// Executor to launch child tasks
private ScheduledThreadPoolExecutor exec;
private ThreadPoolExecutor exec;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exec is only responsible for executing tasks, so ThreadPoolExecutor is currently more suitable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants