2019-10-09 19:59:19 +03:00
|
|
|
package ants
|
|
|
|
|
|
|
|
import "time"
|
|
|
|
|
|
|
|
type workerStack struct {
|
2023-03-23 06:40:06 +03:00
|
|
|
items []worker
|
|
|
|
expiry []worker
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func newWorkerStack(size int) *workerStack {
|
2019-10-20 13:22:13 +03:00
|
|
|
return &workerStack{
|
2023-03-23 06:40:06 +03:00
|
|
|
items: make([]worker, 0, size),
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (wq *workerStack) len() int {
|
|
|
|
return len(wq.items)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (wq *workerStack) isEmpty() bool {
|
|
|
|
return len(wq.items) == 0
|
|
|
|
}
|
|
|
|
|
2023-03-23 06:40:06 +03:00
|
|
|
func (wq *workerStack) insert(w worker) error {
|
|
|
|
wq.items = append(wq.items, w)
|
2019-10-09 19:59:19 +03:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-03-23 06:40:06 +03:00
|
|
|
func (wq *workerStack) detach() worker {
|
2019-10-09 19:59:19 +03:00
|
|
|
l := wq.len()
|
|
|
|
if l == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
w := wq.items[l-1]
|
2020-08-29 13:51:56 +03:00
|
|
|
wq.items[l-1] = nil // avoid memory leaks
|
2019-10-09 19:59:19 +03:00
|
|
|
wq.items = wq.items[:l-1]
|
|
|
|
|
|
|
|
return w
|
|
|
|
}
|
|
|
|
|
2023-03-23 06:40:06 +03:00
|
|
|
func (wq *workerStack) staleWorkers(duration time.Duration) []worker {
|
2019-10-09 19:59:19 +03:00
|
|
|
n := wq.len()
|
|
|
|
if n == 0 {
|
2019-10-09 22:02:04 +03:00
|
|
|
return nil
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
expiryTime := time.Now().Add(-duration)
|
2019-10-20 13:22:13 +03:00
|
|
|
index := wq.binarySearch(0, n-1, expiryTime)
|
2019-10-09 19:59:19 +03:00
|
|
|
|
|
|
|
wq.expiry = wq.expiry[:0]
|
|
|
|
if index != -1 {
|
|
|
|
wq.expiry = append(wq.expiry, wq.items[:index+1]...)
|
|
|
|
m := copy(wq.items, wq.items[index+1:])
|
2020-08-29 13:51:56 +03:00
|
|
|
for i := m; i < n; i++ {
|
|
|
|
wq.items[i] = nil
|
|
|
|
}
|
2019-10-09 19:59:19 +03:00
|
|
|
wq.items = wq.items[:m]
|
|
|
|
}
|
2019-10-09 22:02:04 +03:00
|
|
|
return wq.expiry
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
|
2019-10-20 13:22:13 +03:00
|
|
|
func (wq *workerStack) binarySearch(l, r int, expiryTime time.Time) int {
|
2019-10-09 19:59:19 +03:00
|
|
|
var mid int
|
|
|
|
for l <= r {
|
|
|
|
mid = (l + r) / 2
|
2023-03-23 10:16:21 +03:00
|
|
|
if expiryTime.Before(wq.items[mid].lastUsedTime()) {
|
2019-10-09 19:59:19 +03:00
|
|
|
r = mid - 1
|
|
|
|
} else {
|
|
|
|
l = mid + 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
2019-10-20 13:22:13 +03:00
|
|
|
func (wq *workerStack) reset() {
|
2019-10-09 19:59:19 +03:00
|
|
|
for i := 0; i < wq.len(); i++ {
|
2023-03-23 06:40:06 +03:00
|
|
|
wq.items[i].finish()
|
2020-08-29 13:51:56 +03:00
|
|
|
wq.items[i] = nil
|
2019-10-09 19:59:19 +03:00
|
|
|
}
|
|
|
|
wq.items = wq.items[:0]
|
|
|
|
}
|