github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/ongoing_work_limiter.go (about) 1 package libkbfs 2 3 import "context" 4 5 // OngoingWorkLimiter limits maximum number of routines that can work on a same 6 // type of thing at the same time. For example, it can be used for limiting 7 // number of ongoing rekeys. 8 type OngoingWorkLimiter struct { 9 permits chan struct{} 10 } 11 12 // NewOngoingWorkLimiter creates a new *OngoingWorkLimiter with capacity of 13 // maxNumOngoingWorks. 14 func NewOngoingWorkLimiter(maxNumOngoingWorks int) *OngoingWorkLimiter { 15 return &OngoingWorkLimiter{ 16 permits: make(chan struct{}, maxNumOngoingWorks), 17 } 18 } 19 20 // WaitToStart blocks until the limiter would allow one more routine to start 21 // working on the thing. 22 func (owl *OngoingWorkLimiter) WaitToStart(ctx context.Context) error { 23 select { 24 case owl.permits <- struct{}{}: 25 return nil 26 case <-ctx.Done(): 27 return ctx.Err() 28 } 29 } 30 31 // Done tells the limiter that the caller is done working on the thing, and 32 // somebody else is free to start work. 33 func (owl *OngoingWorkLimiter) Done() { 34 <-owl.permits 35 }