1// Copyright 2016 The Prometheus Authors 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14package gate 15 16import "context" 17 18// A Gate controls the maximum number of concurrently running and waiting queries. 19type Gate struct { 20 ch chan struct{} 21} 22 23// New returns a query gate that limits the number of queries 24// being concurrently executed. 25func New(length int) *Gate { 26 return &Gate{ 27 ch: make(chan struct{}, length), 28 } 29} 30 31// Start blocks until the gate has a free spot or the context is done. 32func (g *Gate) Start(ctx context.Context) error { 33 select { 34 case <-ctx.Done(): 35 return ctx.Err() 36 case g.ch <- struct{}{}: 37 return nil 38 } 39} 40 41// Done releases a single spot in the gate. 42func (g *Gate) Done() { 43 select { 44 case <-g.ch: 45 default: 46 panic("gate.Done: more operations done than started") 47 } 48} 49