Skip to content
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

Add TimerTask#interval_type option to configure interval calculation #997

Merged
merged 1 commit into from
Jan 16, 2024

Conversation

bensheldon
Copy link
Contributor

@bensheldon bensheldon commented May 25, 2023

Can be either :fixed_delay or :fixed_rate, default to :fixed_delay.

Closes #678

Notes:

  • I would love a better suggestion for the parameter than interval_type
  • The option names come from @eregon's suggestion to mirror Java's options

# @!attribute [rw] interval_type
# @return [Symbol] method to calculate the interval between executions, can be either
# :fixed_rate or :fixed_delay; default to :fixed_delay.
def interval_type=(value)
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider removing this as discussed.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed, it should be only set when building a new TimerTask and not changed after

FIXED_RATE = :fixed_rate

# Default `:interval_type`
INTERVAL_TYPE = FIXED_DELAY
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
INTERVAL_TYPE = FIXED_DELAY
DEFAULT_INTERVAL_TYPE = FIXED_DELAY

# Default `:timeout_interval` in seconds.
TIMEOUT_INTERVAL = 30
# Maintain the interval between the end of one execution and the start of the next execution.
FIXED_DELAY = :fixed_delay
Copy link
Contributor

Choose a reason for hiding this comment

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

As discussed, we see a third mode, which could be fixed_rate_drop which drops subsequent executions if the current execution violates the maximum time slice given the rate specified.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah that makes sense to me.

@@ -74,6 +85,12 @@ module Concurrent
#
# #=> 'Boom!'
#
# @example Configuring `:interval_type` with either :fixed_delay or :fixed_rate, default is :fixed_delay
# task = Concurrent::TimerTask.new(execution_interval: 5, interval_type: :fixed_rate) do
Copy link
Contributor

Choose a reason for hiding this comment

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

I personally consider the interval_type to be a static configuration of the behaviour of the application rather than something decided at run-time. Therefore, I wonder if this would be better implemented using sub-classes which implement the specific behaviour required, e.g. FixedRateTimerTask.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Subclasses seem rather heavy for this, and I am concerned that for compatibility we would need to keep Concurrent::TimerTask so it would be both a leaf class and an abstract class, that sounds very confusing.
So I think a constructor argument like here makes most sense and is consistent with what is already done in concurrent-ruby APIs.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why would it be an abstract class?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Why would it be an abstract class?

If you make subclasses the superclass should be abstract. Otherwise I think it's pretty confusing.

Copy link
Contributor

@ioquatix ioquatix left a comment

Choose a reason for hiding this comment

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

I agree with the proposed idea but I have some suggestions about the implementation.

@ioquatix
Copy link
Contributor

@bensheldon if you have time, I suggest we make a 2nd PR which uses a derived class, so we can compare the level of complexity.

@bensheldon
Copy link
Contributor Author

@ioquatix no prob! I'll try to get to that next week.

…ulation

Can be either `:fixed_delay` or `:fixed_rate`, default to `:fixed_delay`
@eregon
Copy link
Collaborator

eregon commented Jan 16, 2024

This looks great, merging, thank you!

@eregon eregon merged commit fb19d0e into ruby-concurrency:master Jan 16, 2024
12 checks passed
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.

TimerTask should schedule next run before doing job
3 participants