Documentation ¶
Overview ¶
Package workpool provies the `Pool` type which functions as a means of managing the number of concurrent workers, grouped by key. You can think of this type as functioning like a collection of semaphores, except that multiple distinct resources may exist (distinguished by keys), and the target concurrent worker count may change at runtime. The basic usage pattern is as follows:
1. The desired number of workers for a given key is specified or updated via Pool.Set.
2. Workers are spawned as leases become available on Pool.Acquire.
3. Workers relenquish their leases when they finish their work by calling Lease.Release.
4. New leases become available as old leases are relenquished, or as the target concurrent lease count increases.
This is a generalization of logic originally written to manage the number of concurrent reversetunnel agents per proxy endpoint.
Example ¶
pool := NewPool(context.TODO()) defer pool.Stop() // create two keys with different target counts pool.Set("spam", 2) pool.Set("eggs", 1) // track how many workers are spawned for each key counts := make(map[string]int) var mu sync.Mutex var wg sync.WaitGroup for i := 0; i < 12; i++ { wg.Add(1) go func() { lease := <-pool.Acquire() defer lease.Release() mu.Lock() counts[lease.Key().(string)]++ mu.Unlock() // in order to demonstrate the differing spawn rates we need // work to take some time, otherwise pool will end up granting // leases in a "round robin" fashion. time.Sleep(time.Millisecond * 10) wg.Done() }() } wg.Wait() // exact counts will vary, but leases with key `spam` // will end up being generated approximately twice as // often as leases with key `eggs`. fmt.Println(counts["spam"] > counts["eggs"])
Output: true
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Counts ¶
type Counts struct { // Target is the number of active leases that we would // like to converge toward. Target uint64 // Active is the current active lease count. Active uint64 }
Counts holds the target and active counts for a key/group.
type Lease ¶
type Lease struct {
// contains filtered or unexported fields
}
Lease grants access to a resource or group. When the lease is received, work can begin. Leases are held by workers and must be released when the worker has finished its work.
type Pool ¶
type Pool struct {
// contains filtered or unexported fields
}
Pool manages a collection of work groups by key and is the primary means by which groups are managed. Each work group has an adjustable target value which is the number of target leases which should be active for the given group.
func (*Pool) Acquire ¶
Acquire is the channel which must be received on to acquire new leases. Each lease acquired in this way *must* have its Release method called when the lease is no longer needed.