go-study/lock_free/delay_queue.go
2024-12-09 10:50:31 +08:00

74 lines
1.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package lock_free
import (
"iter"
"time"
)
type DelayLkQueue[TValue any, TKey comparable] struct {
timers map[TKey]*time.Timer
LkQueue[TValue]
}
// NewDelayLkQueue 创建延迟无锁队列
func NewDelayLkQueue[TValue any, TKey comparable]() *DelayLkQueue[TValue, TKey] {
return &DelayLkQueue[TValue, TKey]{make(map[TKey]*time.Timer), *NewLkQueue[TValue]()}
}
// DelayEnqueue 延迟入队
func (q *DelayLkQueue[TValue, TKey]) DelayEnqueue(value TValue, duration time.Duration) {
time.AfterFunc(duration, func() {
q.Enqueue(value)
})
}
// CancellableDelayEnqueue 可取消的延迟入队
func (q *DelayLkQueue[TValue, TKey]) CancellableDelayEnqueue(key TKey, value TValue, duration time.Duration) {
if timer, ok := q.timers[key]; ok {
timer.Stop()
}
q.timers[key] = time.AfterFunc(duration, func() {
delete(q.timers, key)
q.Enqueue(value)
})
}
// CancelDelayEnqueue 取消延迟入队
func (q *DelayLkQueue[TValue, TKey]) CancelDelayEnqueue(key TKey) {
if timer, ok := q.timers[key]; ok {
delete(q.timers, key)
timer.Stop()
}
}
// ContinuousDequeue 持续监听出队
func (q *DelayLkQueue[TValue, TKey]) ContinuousDequeue() iter.Seq[TValue] {
return func(yield func(TValue) bool) {
for {
if value, ok := q.Dequeue(); ok {
if !yield(value) {
return
}
} else {
time.Sleep(time.Millisecond) // 队列为空休眠1毫秒
}
}
}
}
// ContinuousDequeueExecute 持续监听出队执行函数
func (q *DelayLkQueue[TValue, TKey]) ContinuousDequeueExecute(fn func(TValue)) {
for value := range q.ContinuousDequeue() {
fn(value)
}
}
// ContinuousDequeueNotify 持续监听出队通知
func (q *DelayLkQueue[TValue, TKey]) ContinuousDequeueNotify(chs ...chan TValue) {
q.ContinuousDequeueExecute(func(value TValue) {
for _, ch := range chs {
ch <- value
}
})
}