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 quotas to Permits #3333

Merged
merged 11 commits into from
Mar 9, 2021
Merged

Add quotas to Permits #3333

merged 11 commits into from
Mar 9, 2021

Conversation

ryanhall07
Copy link
Collaborator

Allows a Permit impl to decide how much quota a caller is allowed to use
for each Permit acquired. Having a quota > 1 is a nice performance
optimization to avoid having to acquire a permit everytime a resource is
consumed.

Additionally the new Permit structure allows tracking if a Permit is
acquired/released more than once by a caller using a refCount. Allows
catching bugs in tests by panicing.

What this PR does / why we need it:

Fixes #

Special notes for your reviewer:

Does this PR introduce a user-facing and/or backwards incompatible change?:


Does this PR require updating code package or user-facing documentation?:


Allows a Permit impl to decide how much quota a caller is allowed to use
for each Permit acquired. Having a quota > 1 is a nice performance
optimization to avoid having to acquire a permit everytime a resource is
consumed.

Additionally the new Permit structure allows tracking if a Permit is
acquired/released more than once by a caller using a refCount. Allows
catching bugs in tests by panicing.
@codecov
Copy link

codecov bot commented Mar 7, 2021

Codecov Report

Merging #3333 (3eec0ce) into master (3eec0ce) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #3333   +/-   ##
=======================================
  Coverage    72.5%    72.5%           
=======================================
  Files        1100     1100           
  Lines      103053   103053           
=======================================
  Hits        74768    74768           
  Misses      23149    23149           
  Partials     5136     5136           
Flag Coverage Δ
aggregator 76.7% <0.0%> (ø)
cluster 84.9% <0.0%> (ø)
collector 84.3% <0.0%> (ø)
dbnode 78.9% <0.0%> (ø)
m3em 74.4% <0.0%> (ø)
m3ninx 73.6% <0.0%> (ø)
metrics 19.8% <0.0%> (ø)
msg 74.6% <0.0%> (ø)
query 67.3% <0.0%> (ø)
x 80.3% <0.0%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3eec0ce...76ca76c. Read the comment docs.

@ryanhall07 ryanhall07 marked this pull request as ready for review March 8, 2021 03:07
@@ -939,17 +937,11 @@ type fetchTaggedResultsIterOpts struct {
}

func newFetchTaggedResultsIter(opts fetchTaggedResultsIterOpts) FetchTaggedResultsIter { //nolint: gocritic
_, limitBased := opts.blockPermits.(*permits.LookbackLimitPermit)
Copy link
Collaborator

Choose a reason for hiding this comment

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

So nice to be able to get rid of this

Copy link
Collaborator

@wesleyk wesleyk left a comment

Choose a reason for hiding this comment

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

LGTM

if i.idx == idx {
// block acquiring if we need the block readers to fulfill the current fetch.
if err := i.blockPermits.Acquire(ctx); err != nil {
permit, err := i.blockPermits.Acquire(ctx)
if err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

interesting; so if we do run into an error, we don't technically release all held permits? Or is that handled elsewhere? (separate comment from your change I think)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

when an error happens, the fetched tagged iterator is closed, which releases all held permits.


// mutable state
quotaUsed int64
refCount atomic.Int32
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we call out that this should be 0 or 1?

}

// Permit is granted to a caller which is allowed to consume some amount of quota.
type Permit interface {
Copy link
Collaborator

Choose a reason for hiding this comment

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

hmm, callers should never invoke release or acquire, fair to say? I guess the panics help guard that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

correct. I couldn't think of a better name. maybe PrepareForRelease and PrepareForAcquire?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

or maybe PostRelease and PreAcquire, kind of like hooks for the managers to call

@ryanhall07 ryanhall07 merged commit ffdce8e into master Mar 9, 2021
@ryanhall07 ryanhall07 deleted the rhall-release-quotas branch March 9, 2021 02:46
soundvibe added a commit that referenced this pull request Mar 9, 2021
* master: (22 commits)
  Remove deprecated fields (#3327)
  Add quotas to Permits (#3333)
  [aggregator] Drop messages that have a drop policy applied (#3341)
  Fix NPE due to race with a closing series (#3056)
  [coordinator] Apply auto-mapping rules if-and-only-if no drop policies are in effect (#3339)
  [aggregator] Add validation in AddTimedWithStagedMetadatas (#3338)
  [coordinator] Fix panic in Ready endpoint for admin coordinator (#3335)
  [instrument] Config option to emit detailed Go runtime metrics only (#3332)
  [aggregator] Sort heap in one go, instead of iterating one-by-one (#3331)
  [pool] Add support for dynamic, sync.Pool backed, object pools (#3334)
  Enable PANIC_ON_INVARIANT_VIOLATED for tests (#3326)
  [aggregator] CanLead for unflushed window takes BufferPast into account (#3328)
  Optimize StagedMetadatas conversion (#3330)
  [m3msg] Improve message scan performance (#3319)
  [dbnode] Add reason tag to bootstrap retries metric (#3317)
  [coordinator] Enable rule filtering on prom metric type (#3325)
  Update m3dbnode-all-config.yml (#3204)
  [coordinator] Include Type in RollupOp.Equal (#3322)
  [coordinator] Simplify iteration logic of matchRollupTarget (#3321)
  [coordinator] Add rollup type to remove specific dimensions (#3318)
  ...
processingTime := time.Since(startProcessing)
queryMetrics.blockProcessingTime.RecordDuration(processingTime)
blockIter.processingTime += processingTime
permits.Release(int64(processingTime))
permit.Use(int64(processingTime))
Copy link
Contributor

@asafm asafm Jun 20, 2021

Choose a reason for hiding this comment

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

@ryanhall07 What's the motivation for calling .Use on the permit, if a line later it is immediately released, hence you're not using that information anywhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

so the Permit can track how much of the allowed quota was actually used. impls of the Permits may care to know about this information.

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.

4 participants