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

[broker] Add config to allow deliverAt time to be strictly honored #16068

Conversation

michaeljmarshall
Copy link
Member

@michaeljmarshall michaeljmarshall commented Jun 15, 2022

Motivation

The current implementation for InMemoryDelayedDeliveryTracker allows messages to deliver early when their deliverAt time is within tickTimeMillis from now. This is an optimization that ensures messages deliver around the deliverAt time. However, some use cases require that messages do not deliver before the deliverAt time. (Note that the client api includes a deliverAfter method that implies messages won't deliver before some duration of time.)

In order to support this alternative implementation, this PR adds a broker configuration named isDelayedDeliveryDeliverAtTimeStrict. When true, messages will only deliver when the deliverAt time is greater than or equal to now. Note that a tradeoff here is that messages will be later than the deliverAt time.

There are two factors that will determine how late messages will get to consumers. The first is the topic's DelayedDeliveryTickTimeMillis and the second is the broker's delayedDeliveryTickTimeMillis. The first will determine how frequently a timer will be scheduled to deliver delayed messages. The second is used to determine the tick time of the HashedWheelTimer, and as a result, can compound with the topic's delay to make a message deliver even later.

Modifications

  • Add broker config named isDelayedDeliveryDeliverAtTimeStrict. This config defaults to false to maintain the original behavior.
  • Update the InMemoryDelayedDeliveryTracker#addMessage method so that it will return false when deliverAt <= getCutoffTime() instead of just deliverAt <= getCutoffTime().
  • Update documentation in several places.
  • Implement InMemoryDelayedDeliveryTracker#getCutoffTime method that returns the right cutoff time based on the value of isDelayedDeliveryDeliverAtTimeStrict. This is the core logical change.
  • Update InMemoryDelayedDeliveryTracker#updateTimer so that it will not schedule a tick to run sooner that the most recent tick run plus the tickTimeMillis. This will ensure the timer is not run too frequently. It is also backwards compatible since the existing feature will deliver any messages that were within now plus the tickTimeMillis.
  • Add new tests to cover the new configuration.

Verifying this change

New tests are added as part of this change.

Does this pull request potentially affect one of the following parts:

This is a new feature that maintains backwards compatibility.

  • doc

@michaeljmarshall michaeljmarshall added doc Your PR contains doc changes, no matter whether the changes are in markdown or code files. type/feature The PR added a new feature or issue requested a new feature area/broker labels Jun 15, 2022
@michaeljmarshall michaeljmarshall added this to the 2.11.0 milestone Jun 15, 2022
@michaeljmarshall michaeljmarshall self-assigned this Jun 15, 2022
Copy link
Member

@lhotari lhotari left a comment

Choose a reason for hiding this comment

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

LGTM. Good work @michaeljmarshall

Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

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

LGTM

@lhotari lhotari requested a review from codelipenghui June 15, 2022 07:39
Copy link
Contributor

@codelipenghui codelipenghui left a comment

Choose a reason for hiding this comment

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

LGTM, just left a comment about the configuration description.

@michaeljmarshall michaeljmarshall merged commit b8835bb into apache:master Jun 16, 2022
@michaeljmarshall michaeljmarshall deleted the make-strict-delayed-delivery-configurable branch June 16, 2022 05:40
merlimat pushed a commit that referenced this pull request Jul 15, 2022
…16068)

* [broker] Add config to allow deliverAt time to be strictly honored

* Fix checkstyle error (this is what happens why you change names last minute)

* Improve documentation; add private final modifiers

The current implementation for `InMemoryDelayedDeliveryTracker` allows messages to deliver early when their `deliverAt` time is within `tickTimeMillis` from now. This is an optimization that ensures messages deliver around the `deliverAt` time. However, some use cases require that messages do not deliver before the `deliverAt` time. (Note that the client api includes a `deliverAfter` method that implies messages won't deliver before some duration of time.)

In order to support this alternative implementation, this PR adds a broker configuration named `isDelayedDeliveryDeliverAtTimeStrict`. When true, messages will only deliver when the `deliverAt` time is greater than or equal to `now`. Note that a tradeoff here is that messages will be later than the `deliverAt` time.

There are two factors that will determine how late messages will get to consumers. The first is the topic's `DelayedDeliveryTickTimeMillis` and the second is the broker's `delayedDeliveryTickTimeMillis`. The first will determine how frequently a timer will be scheduled to deliver delayed messages. The second is used to determine the tick time of the `HashedWheelTimer`, and as a result, can compound with the topic's delay to make a message deliver even later.

* Add broker config named `isDelayedDeliveryDeliverAtTimeStrict`. This config defaults to `false` to maintain the original behavior.
* Update the `InMemoryDelayedDeliveryTracker#addMessage` method so that it will return false when `deliverAt <= getCutoffTime()` instead of just `deliverAt <= getCutoffTime()`.
* Update documentation in several places.
* Implement `InMemoryDelayedDeliveryTracker#getCutoffTime` method that returns the right cutoff time based on the value of `isDelayedDeliveryDeliverAtTimeStrict`. This is the core logical change.
* Update `InMemoryDelayedDeliveryTracker#updateTimer` so that it will not schedule a tick to run sooner that the most recent tick run plus the `tickTimeMillis`. This will ensure the timer is not run too frequently. It is also backwards compatible since the existing feature will deliver any messages that were within now plus the `tickTimeMillis`.
* Add new tests to cover the new configuration.

New tests are added as part of this change.

This is a new feature that maintains backwards compatibility.
merlimat pushed a commit that referenced this pull request Jul 15, 2022
…16068)

* [broker] Add config to allow deliverAt time to be strictly honored

* Fix checkstyle error (this is what happens why you change names last minute)

* Improve documentation; add private final modifiers

The current implementation for `InMemoryDelayedDeliveryTracker` allows messages to deliver early when their `deliverAt` time is within `tickTimeMillis` from now. This is an optimization that ensures messages deliver around the `deliverAt` time. However, some use cases require that messages do not deliver before the `deliverAt` time. (Note that the client api includes a `deliverAfter` method that implies messages won't deliver before some duration of time.)

In order to support this alternative implementation, this PR adds a broker configuration named `isDelayedDeliveryDeliverAtTimeStrict`. When true, messages will only deliver when the `deliverAt` time is greater than or equal to `now`. Note that a tradeoff here is that messages will be later than the `deliverAt` time.

There are two factors that will determine how late messages will get to consumers. The first is the topic's `DelayedDeliveryTickTimeMillis` and the second is the broker's `delayedDeliveryTickTimeMillis`. The first will determine how frequently a timer will be scheduled to deliver delayed messages. The second is used to determine the tick time of the `HashedWheelTimer`, and as a result, can compound with the topic's delay to make a message deliver even later.

* Add broker config named `isDelayedDeliveryDeliverAtTimeStrict`. This config defaults to `false` to maintain the original behavior.
* Update the `InMemoryDelayedDeliveryTracker#addMessage` method so that it will return false when `deliverAt <= getCutoffTime()` instead of just `deliverAt <= getCutoffTime()`.
* Update documentation in several places.
* Implement `InMemoryDelayedDeliveryTracker#getCutoffTime` method that returns the right cutoff time based on the value of `isDelayedDeliveryDeliverAtTimeStrict`. This is the core logical change.
* Update `InMemoryDelayedDeliveryTracker#updateTimer` so that it will not schedule a tick to run sooner that the most recent tick run plus the `tickTimeMillis`. This will ensure the timer is not run too frequently. It is also backwards compatible since the existing feature will deliver any messages that were within now plus the `tickTimeMillis`.
* Add new tests to cover the new configuration.

New tests are added as part of this change.

This is a new feature that maintains backwards compatibility.
momo-jun added a commit to momo-jun/pulsar that referenced this pull request Dec 9, 2022
momo-jun added a commit to momo-jun/pulsar that referenced this pull request Dec 9, 2022
momo-jun added a commit to momo-jun/pulsar that referenced this pull request Dec 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/broker cherry-picked/branch-2.9 Archived: 2.9 is end of life doc Your PR contains doc changes, no matter whether the changes are in markdown or code files. release/2.9.4 type/feature The PR added a new feature or issue requested a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants