diff options
author | John Cai <jcai@gitlab.com> | 2022-05-17 19:40:25 +0300 |
---|---|---|
committer | John Cai <jcai@gitlab.com> | 2022-05-17 19:40:25 +0300 |
commit | 7f286a1565ad7990e10f75ab328fe0da65c39fc8 (patch) | |
tree | 5b94d7ce44bc496a542fd18bdff2a37d2fbea66e | |
parent | 9d6e877727a092094c2900a5db7ddae1a9969904 (diff) |
featureflag: Remove ConcurrencyQueueMaxWait feature flagjc-remove-queue-wait-ff
We can remove this feature flag now that we've been running in
production with this flag on for a few weeks now without issue.
4 files changed, 56 insertions, 123 deletions
diff --git a/internal/metadata/featureflag/ff_max_queue_wait_time.go b/internal/metadata/featureflag/ff_max_queue_wait_time.go deleted file mode 100644 index 2cd281a5b..000000000 --- a/internal/metadata/featureflag/ff_max_queue_wait_time.go +++ /dev/null @@ -1,5 +0,0 @@ -package featureflag - -// ConcurrencyQueueMaxWait will enable the concurrency limiter to drop requests that are waiting in -// the concurrency queue for longer than the configured time. -var ConcurrencyQueueMaxWait = NewFeatureFlag("concurrency_queue_max_wait", false) diff --git a/internal/middleware/limithandler/concurrency_limiter.go b/internal/middleware/limithandler/concurrency_limiter.go index bec438b25..af09a57fe 100644 --- a/internal/middleware/limithandler/concurrency_limiter.go +++ b/internal/middleware/limithandler/concurrency_limiter.go @@ -51,8 +51,7 @@ type semaphoreReference struct { func (sem *semaphoreReference) acquire(ctx context.Context) error { var ticker helper.Ticker - if featureflag.ConcurrencyQueueMaxWait.IsEnabled(ctx) && - sem.newTicker != nil { + if sem.newTicker != nil { ticker = sem.newTicker() } else { ticker = helper.Ticker(helper.NewManualTicker()) diff --git a/internal/middleware/limithandler/concurrency_limiter_test.go b/internal/middleware/limithandler/concurrency_limiter_test.go index 6c19fec2b..31d9020f4 100644 --- a/internal/middleware/limithandler/concurrency_limiter_test.go +++ b/internal/middleware/limithandler/concurrency_limiter_test.go @@ -356,117 +356,59 @@ func (b *blockingDequeueCounter) Dequeued(context.Context) { func TestLimitConcurrency_queueWaitTime(t *testing.T) { ctx := testhelper.Context(t) - t.Run("with feature flag", func(t *testing.T) { - ctx = featureflag.IncomingCtxWithFeatureFlag( - ctx, - featureflag.ConcurrencyQueueMaxWait, - true, - ) - - ticker := helper.NewManualTicker() - - dequeuedCh := make(chan struct{}) - monitor := &blockingDequeueCounter{dequeuedCh: dequeuedCh} - - limiter := NewConcurrencyLimiter( - 1, - 0, - func() helper.Ticker { - return ticker - }, - monitor, - ) - - ch := make(chan struct{}) - var wg sync.WaitGroup - wg.Add(1) - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - <-ch - return nil, nil - }) - require.NoError(t, err) - wg.Done() - }() - - <-dequeuedCh - - ticker.Tick() - - errChan := make(chan error) - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - return nil, nil - }) - errChan <- err - }() - - <-dequeuedCh - err := <-errChan - - s, ok := status.FromError(err) - require.True(t, ok) - details := s.Details() - require.Len(t, details, 1) - - limitErr, ok := details[0].(*gitalypb.LimitError) - require.True(t, ok) - - assert.Equal(t, ErrMaxQueueTime.Error(), limitErr.ErrorMessage) - assert.Equal(t, durationpb.New(0), limitErr.RetryAfter) - - assert.Equal(t, monitor.droppedTime, 1) - close(ch) - wg.Wait() - }) - - t.Run("without feature flag", func(t *testing.T) { - ctx = featureflag.IncomingCtxWithFeatureFlag( - ctx, - featureflag.ConcurrencyQueueMaxWait, - false, - ) - - ticker := helper.NewManualTicker() - - dequeuedCh := make(chan struct{}) - monitor := &blockingDequeueCounter{dequeuedCh: dequeuedCh} - - limiter := NewConcurrencyLimiter( - 1, - 0, - func() helper.Ticker { - return ticker - }, - monitor, - ) - - ch := make(chan struct{}) - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - <-ch - return nil, nil - }) - require.NoError(t, err) - }() - - <-dequeuedCh - - ticker.Tick() - - errChan := make(chan error) - go func() { - _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { - return nil, nil - }) - errChan <- err - }() - - close(ch) - <-dequeuedCh - err := <-errChan - - assert.NoError(t, err) - assert.Equal(t, monitor.droppedTime, 0) - }) + ticker := helper.NewManualTicker() + + dequeuedCh := make(chan struct{}) + monitor := &blockingDequeueCounter{dequeuedCh: dequeuedCh} + + limiter := NewConcurrencyLimiter( + 1, + 0, + func() helper.Ticker { + return ticker + }, + monitor, + ) + + ch := make(chan struct{}) + var wg sync.WaitGroup + wg.Add(1) + go func() { + _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { + <-ch + return nil, nil + }) + require.NoError(t, err) + wg.Done() + }() + + <-dequeuedCh + + ticker.Tick() + + errChan := make(chan error) + go func() { + _, err := limiter.Limit(ctx, "key", func() (interface{}, error) { + return nil, nil + }) + errChan <- err + }() + + <-dequeuedCh + err := <-errChan + + s, ok := status.FromError(err) + require.True(t, ok) + details := s.Details() + require.Len(t, details, 1) + + limitErr, ok := details[0].(*gitalypb.LimitError) + require.True(t, ok) + + assert.Equal(t, ErrMaxQueueTime.Error(), limitErr.ErrorMessage) + assert.Equal(t, durationpb.New(0), limitErr.RetryAfter) + + assert.Equal(t, monitor.droppedTime, 1) + close(ch) + wg.Wait() } diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go index f3a917c70..c1c1c4f56 100644 --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -174,9 +174,6 @@ func ContextWithoutCancel(opts ...ContextOpt) context.Context { // ConcurrencyQueueEnforceMax is in the codepath of every RPC call since its in the limithandler // middleware. ctx = featureflag.ContextWithFeatureFlag(ctx, featureflag.ConcurrencyQueueEnforceMax, true) - // ConcurrencyQueueMaxWait is in the codepath of every RPC call since it's in the limithandler - // middleware. - ctx = featureflag.ContextWithFeatureFlag(ctx, featureflag.ConcurrencyQueueMaxWait, true) // Randomly inject the Git flag so that we have coverage of tests with both old and new Git // version by pure chance. ctx = featureflag.ContextWithFeatureFlag(ctx, featureflag.GitV2361Gl1, rnd.Int()%2 == 0) |