diff --git a/lib.go b/lib.go index 69ea972..fbd1173 100644 --- a/lib.go +++ b/lib.go @@ -73,8 +73,7 @@ const ( AllEvents = GetOperation | PutOperation | AllocateOperation | LoadOperation | FreeOperation | AllocateError ) -// Event values are sent by the pool after various operations, if it is configured to use a channel the send the -// events to. +// Event values are sent by the pool after various operations, if a channel is provided to send the events to. type Event struct { // Type is the binary flag depicting the type of the event. @@ -92,11 +91,11 @@ type Algo interface { // Target is called on every Put operation with the current pool state as the input. It is expected to // return the target idle count, as dictated by the implementing algorithm. Optionally, a timeout value // can be returned (nextCheck), and if it is a positive value, the pool will call Target again after the - // defined time expires to see if the next target idle count. In each case, when Target returns a - // smaller number than the current idle count, it shrinks the pool to the defined target. + // defined time expires to fetch the next target idle count. In each case, when Target returns a smaller + // number than the current idle count, it shrinks the pool to the defined target. // - // When using nextCheck, not every returned nextCheck results in calling Target by the pool, only the - // ones that were set after the previous one expired. + // When using nextCheck, not every returned value results in calling Target by the pool, only the ones + // that were set after the previous check expired. // // Implementations should consider that while the recommended way of using the pool is to only call Put // with items that were received by calling Get, the pool itself doesn't prohibit calling Put with @@ -114,10 +113,10 @@ type Algo interface { // scenarios. type Options struct { - // Events is a channel that, when set, the pool is using for sending events. The channel needs to be - // used together with a non-default event mask set. When using events, we should consider to use a - // buffered channel. Events can be dropped if the consumer is blocked and the channel is not ready to - // communicate at the time of the event. + // Events is a channel that, when set, the pool uses to send events. The channel needs to be used + // together with a non-default event mask set. When using events, we should consider using a buffered + // channel. Events can be dropped if the consumer is blocked and the channel is not ready to communicate + // at the time of the event. Events chan<- Event // EventMask is a binary flag that defines which events will be sent to the provided channel. The @@ -132,13 +131,13 @@ type Options struct { Clock times.Clock // TestBus is an optional signal bus meant to be used with testing. The main purpose is to ensure that - // specific blocks of code are executed in a predefiend order during concurrent tests. + // specific blocks of code are executed in a predefined order during concurrent tests. TestBus *syncbus.SyncBus } -// Pool is a synchronized resource pool of resources, that are considered expensive to allocate. Initialize the -// pool with the Make() function. Methods of uninitialized Pool instances may block forever. For the usage of -// the pool, see the docs of its method, initialization options and the provided algorithms. +// Pool is a synchronized pool of resources that are considered expensive to allocate. Initialize the pool with +// the Make() function. Methods of uninitialized Pool instances may block forever. For the usage of the pool, +// see the docs of its methods, initialization options and the provided algorithms. type Pool[R any] struct { pool pool[R] } @@ -201,31 +200,32 @@ func (s Stats) String() string { // Adaptive creates a zero-config pool shrink algorithm instance. It is the default algorithm used by the pool. // -// It is based on exponential moving average of the active items and the deviation of it. This way it can react +// It is based on the exponential moving average of the active items and their deviation. This way it can react // to, and to some extent overbuild, on the perceived stress. It decays the number of idle items gradually, and // on very sudden drops in traffic, it ensures the eventual release of all pooled items with an internal -// background job, that is timed based on the duration of the last active usage session, which is the time while -// there were active items. Together with the pool implementation, it always reuses the most recent items, as in -// LIFO for Get and FIFO for Free. +// background job. This job is timed based on the duration of the last active usage session (the period during +// which there were active items). Together with the pool implementation, it always reuses the most recent +// items, as in LIFO for Get and FIFO for Free. // // We need to be aware of some potential caveats due to its zero-config nature. Because it relies on the // sequence of operations rather than wall-clock thresholds for its core logic, the algorithm treats rapid // spikes and gradual surges similarly if the sequence of pool states is identical. In short, it can happen -// that: __/\__/\__/\__ = _|_|_|_. It prioritize maintaining sufficient 'headroom' based on observed volatility. +// that: __/\__/\__/\__ = _|_|_|_. It prioritizes maintaining sufficient 'headroom' based on observed +// volatility. func Adaptive() Algo { return makeAdaptiveAlgo() } // MaxTimeout creates a pool shrink algorithm instance, that releases items whenever the number of idle items -// would be greater than max, and it also releases those items that were idle for too long. Together with the -// pool, it ensures that the Get operation is LIFO and the Free operation is FIFO. +// exceeds max, and it also releases those items that were idle for too long. Together with the pool, it ensures +// that the Get operation is LIFO and the Free operation is FIFO. // // If max <= 0, the max pool size is not enforced. If to <= 0, the timeout is not enforced. func MaxTimeout(max int, to time.Duration) Algo { return makeMaxTimeout(max, to) } -// Max is like MaxTimeout, but without the mas idle time. +// Max is like MaxTimeout, but without the max idle time. func Max(max int) Algo { return makeMaxTimeout(max, 0) } @@ -243,10 +243,10 @@ func NoShrink() Algo { // Make initializes a Pool instance. // -// The paramter alloc is used on Get operations when the pool is empty. If alloc is nil, and the pool is empty +// The parameter alloc is used on Get operations when the pool is empty. If alloc is nil, and the pool is empty // at the time of calling Get, Get will return ErrEmpty. If alloc returns an error, the same error is returned -// by Get. If events were configured, alloc triggers AllocateOperation event. This event is typically the same -// as the GetOperation event. +// by Get. If events were configured, alloc triggers an AllocateOperation event. This event is typically the +// same as the GetOperation event. // // The parameter free is called when an item is released from the pool, with the item being released as the // argument. It can be nil for resource types that don't need explicit deallocation. If events were configured, @@ -273,8 +273,8 @@ func (p Pool[R]) Put(i R) { } // Load can be used to populate the pool with items that were not allocated as the result of the Get operation. -// It can be useful in scenarios where prewarming or preparation for an expected sudden traffic spike is -// expected. If events were configured, it triggers a LoadOperation event. +// It can be useful in scenarios where prewarming or preparing for a sudden traffic spike is necessary. If +// events were configured, it triggers a LoadOperation event. func (p Pool[R]) Load(i []R) { p.pool.load(i) } diff --git a/readme.md b/readme.md index 51db2f2..0a427d9 100644 --- a/readme.md +++ b/readme.md @@ -4,10 +4,10 @@ The pool module provides a resource pool implementation that is safe to access f It supports: -- explicitly finalizing items when shrinking the pool +- finalizing the items when shrinking the pool - monitoring the pool usage and state with events and statistics - max idle size and timeout based shrinking algorithms -- a zero-config adaptive algorithm that can automatically adapt to changing resource usage characteristics +- a zero-config adaptive algorithm that automatically follows changing resource usage characteristics - it also accepts custom algorithm implementations Find the documentation here: