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

Provide a shard ownership-based rate limit quota scaler from the history/shard package #4704

Merged
merged 1 commit into from Aug 1, 2023

Conversation

MichaelSnowden
Copy link
Contributor

What changed?
I added code to the history/shard package which supplies the shard controller to the ownership-based rate limit quota scaler, so that it can be used to get the shard count. Basically, this PR adds the plumbing needed to propagate the shard count from the shard controller to the quota scaler, so that clients can just grab an OwnershipBasedQuotaScaler from the fx graph, and then call scaler.ScaleRateBurst(rb) without thinking about any other dependencies.

Why?
So that we can have rate limit quotas in the history service that scale with the approximate workload of the service.

How did you test it?
I added tests which verify that shard counts are propagated to subscribers whenever acquire shards completes. I also verified that this does not block if the subscriber is not listening.

Potential risks
The changes to ControllerImpl here come with a risk because the shard controller is such an essential part of the history service.

Is hotfix candidate?
No.

Comment on lines -33 to -36
var Module = fx.Options(
fx.Provide(ControllerProvider),
fx.Provide(ContextFactoryProvider),
fx.Provide(fx.Annotate(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Two reasons for removing this:

  1. fx.Provide is variadic, so you don't need multiple statements
  2. fx.Options usage is discouraged; the docs read, "Use this pattern sparingly, since it limits the user's ability to customize their application." On its own, it's fine, but it allows you to embed other modules, which induces the problem that quote is talking about because you're choosing the inputs to the module for the user instead of letting them do so.

Copy link
Member

Choose a reason for hiding this comment

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

Does fx.Provide work with Decorate or Replace? I remember using fx.Module can limit the scope of those functions, which in most cases are ideal. I kinda think we should change all var Module = fx.Options(...) in our codebase to a real fx.Module.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Decorate and Replace can be used by clients of this module just as easily as they could if this were an fx.Module. I don't think there's a point in libraries defining their own fx.Module objects because, if a client wants to limit the scope of a graph augmentor (decorate or replace), their code will basically look the exact same: fx.Module(name, library.SomeModule, fx.{Decorate,Replace}(...)) regardless of whether the library SomeModule is defined using fx.Provide, fx.Options or fx.Module because the clients still need to define their own module around it in order to limit their augmentor's scope--they can't put anything inside of an already-defined module.

service/history/shard/controller_impl.go Outdated Show resolved Hide resolved
service/history/shard/controller_impl.go Outdated Show resolved Hide resolved
Comment on lines -33 to -36
var Module = fx.Options(
fx.Provide(ControllerProvider),
fx.Provide(ContextFactoryProvider),
fx.Provide(fx.Annotate(
Copy link
Member

Choose a reason for hiding this comment

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

Does fx.Provide work with Decorate or Replace? I remember using fx.Module can limit the scope of those functions, which in most cases are ideal. I kinda think we should change all var Module = fx.Options(...) in our codebase to a real fx.Module.

}
// shardCountSubscription is a subscription to shard count updates.
shardCountSubscription struct {
controller *ControllerImpl
Copy link
Member

Choose a reason for hiding this comment

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

nit: not sure if using a callback will be better here instead of referencing and mutating controller state directly, but no strong opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried this, but it looked too complicated

@MichaelSnowden MichaelSnowden merged commit fb1d507 into master Aug 1, 2023
10 checks passed
@MichaelSnowden MichaelSnowden deleted the snowden/shard-counter branch August 1, 2023 17:04
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.

None yet

2 participants