add function to drop items taken from but not returned to the pool
This commit is contained in:
parent
8cbcba8458
commit
cde2ec1e6c
31
lib.go
31
lib.go
@ -31,6 +31,10 @@ type Stats struct {
|
|||||||
// Put is the number of put operations during the entire life cycle of the pool.
|
// Put is the number of put operations during the entire life cycle of the pool.
|
||||||
Put int
|
Put int
|
||||||
|
|
||||||
|
// Drop is the number of items dropped without putting them back into the pool, during the entire life
|
||||||
|
// cycle of the pool.
|
||||||
|
Drop int
|
||||||
|
|
||||||
// Alloc is the number of allocations executed by the pool during the entire life cycle of the pool.
|
// Alloc is the number of allocations executed by the pool during the entire life cycle of the pool.
|
||||||
Alloc int
|
Alloc int
|
||||||
|
|
||||||
@ -56,6 +60,9 @@ const (
|
|||||||
// PutOperation is the type of events sent after a put operation.
|
// PutOperation is the type of events sent after a put operation.
|
||||||
PutOperation
|
PutOperation
|
||||||
|
|
||||||
|
// DropOperation is the type of events sent after a drop operation.
|
||||||
|
DropOperation
|
||||||
|
|
||||||
// AllocateOperation is the type of events sent after an allocate operation.
|
// AllocateOperation is the type of events sent after an allocate operation.
|
||||||
AllocateOperation
|
AllocateOperation
|
||||||
|
|
||||||
@ -70,7 +77,13 @@ const (
|
|||||||
AllocateError
|
AllocateError
|
||||||
|
|
||||||
// AllEvents can be used as a mask that includes all the event types.
|
// AllEvents can be used as a mask that includes all the event types.
|
||||||
AllEvents = GetOperation | PutOperation | AllocateOperation | LoadOperation | FreeOperation | AllocateError
|
AllEvents = GetOperation |
|
||||||
|
PutOperation |
|
||||||
|
DropOperation |
|
||||||
|
AllocateOperation |
|
||||||
|
LoadOperation |
|
||||||
|
FreeOperation |
|
||||||
|
AllocateError
|
||||||
)
|
)
|
||||||
|
|
||||||
// Event values are sent by the pool after various operations, if a channel is provided to send the events to.
|
// Event values are sent by the pool after various operations, if a channel is provided to send the events to.
|
||||||
@ -156,6 +169,10 @@ func (et EventType) String() string {
|
|||||||
s = append(s, "put")
|
s = append(s, "put")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if et&DropOperation != 0 {
|
||||||
|
s = append(s, "drop")
|
||||||
|
}
|
||||||
|
|
||||||
if et&AllocateOperation != 0 {
|
if et&AllocateOperation != 0 {
|
||||||
s = append(s, "allocate")
|
s = append(s, "allocate")
|
||||||
}
|
}
|
||||||
@ -187,11 +204,12 @@ func (ev Event) String() string {
|
|||||||
// String returns the string representation of a set of statistics about the pool.
|
// String returns the string representation of a set of statistics about the pool.
|
||||||
func (s Stats) String() string {
|
func (s Stats) String() string {
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"idle: %d, active: %d, get: %d, put: %d, alloc: %d, load: %d, free: %d",
|
"idle: %d, active: %d, get: %d, put: %d, drop: %d, alloc: %d, load: %d, free: %d",
|
||||||
s.Idle,
|
s.Idle,
|
||||||
s.Active,
|
s.Active,
|
||||||
s.Get,
|
s.Get,
|
||||||
s.Put,
|
s.Put,
|
||||||
|
s.Drop,
|
||||||
s.Alloc,
|
s.Alloc,
|
||||||
s.Load,
|
s.Load,
|
||||||
s.Free,
|
s.Free,
|
||||||
@ -272,6 +290,15 @@ func (p Pool[R]) Put(i R) {
|
|||||||
p.pool.put(i)
|
p.pool.put(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drop indicates to the pool that an item received by Get was dropped and will not be put back into the pool.
|
||||||
|
//
|
||||||
|
// While it's not mandatory call it when item was dropped, it has a twofold purpose. Depending on the shrinking
|
||||||
|
// algorithm, it may work more consistently, if the algorithm is notified about the change in the active items.
|
||||||
|
// The other purpose is to allow the pool to reflect these cases in the events and the stats.
|
||||||
|
func (p Pool[R]) Drop() {
|
||||||
|
p.pool.drop()
|
||||||
|
}
|
||||||
|
|
||||||
// Load can be used to populate the pool with items that were not allocated as the result of the Get operation.
|
// 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 preparing for a sudden traffic spike is necessary. If
|
// 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.
|
// events were configured, it triggers a LoadOperation event.
|
||||||
|
|||||||
26
pool.go
26
pool.go
@ -146,6 +146,32 @@ func (p pool[R]) put(r R) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p pool[R]) drop() {
|
||||||
|
s := <-p.state
|
||||||
|
defer func() {
|
||||||
|
p.state <- s
|
||||||
|
}()
|
||||||
|
|
||||||
|
var event EventType
|
||||||
|
event |= DropOperation
|
||||||
|
s.stats.Drop++
|
||||||
|
if s.stats.Active > 0 {
|
||||||
|
s.stats.Active--
|
||||||
|
}
|
||||||
|
|
||||||
|
t, f := p.options.Algo.Target(s.stats)
|
||||||
|
if t < len(s.items) {
|
||||||
|
event |= FreeOperation
|
||||||
|
s = p.freeItems(s, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.stats.Idle = len(s.items)
|
||||||
|
p.sendEvent(event, s.stats)
|
||||||
|
if f > 0 {
|
||||||
|
s = p.forcedCheck(s, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p pool[R]) load(i []R) {
|
func (p pool[R]) load(i []R) {
|
||||||
s := <-p.state
|
s := <-p.state
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|||||||
19
pool_test.go
19
pool_test.go
@ -323,4 +323,23 @@ func TestPool(t *testing.T) {
|
|||||||
t.Fatal(s)
|
t.Fatal(s)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("drop", func(t *testing.T) {
|
||||||
|
alloc := func() ([]byte, error) { return make([]byte, 1<<9), nil }
|
||||||
|
p := pool.Make(alloc, nil, pool.Options{})
|
||||||
|
_, err := p.Get()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s := p.Stats()
|
||||||
|
e := pool.Stats{Alloc: 1, Get: 1, Active: 1}
|
||||||
|
if s != e {
|
||||||
|
t.Fatal(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Drop()
|
||||||
|
s = p.Stats()
|
||||||
|
e = pool.Stats{Alloc: 1, Get: 1, Drop: 1}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user