mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 00:10:25 +08:00 
			
		
		
		
	@@ -114,13 +114,16 @@ func (s *DelayQueue[T]) Dequeue(ctx context.Context) (T, bool) {
 | 
			
		||||
			// 等待时间到期或新元素加入
 | 
			
		||||
			timer := time.NewTimer(delay)
 | 
			
		||||
			select {
 | 
			
		||||
			case elm := <-s.transferChan:
 | 
			
		||||
				return elm, true
 | 
			
		||||
			case <-s.enqueuedSignal:
 | 
			
		||||
				continue
 | 
			
		||||
			case <-timer.C:
 | 
			
		||||
				continue
 | 
			
		||||
			case elm := <-s.transferChan:
 | 
			
		||||
				timer.Stop()
 | 
			
		||||
				return elm, true
 | 
			
		||||
			case <-s.enqueuedSignal:
 | 
			
		||||
				timer.Stop()
 | 
			
		||||
				continue
 | 
			
		||||
			case <-ctx.Done():
 | 
			
		||||
				timer.Stop()
 | 
			
		||||
				return s.zero, false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -187,12 +190,14 @@ func (s *DelayQueue[T]) Enqueue(ctx context.Context, val T) bool {
 | 
			
		||||
			// 新元素需要延迟,等待退出信号、出队信号和到期信号
 | 
			
		||||
			timer := time.NewTimer(delay)
 | 
			
		||||
			select {
 | 
			
		||||
			case <-s.dequeuedSignal:
 | 
			
		||||
				// 收到出队信号,从头开始尝试入队
 | 
			
		||||
				continue
 | 
			
		||||
			case <-timer.C:
 | 
			
		||||
				// 新元素不再需要延迟
 | 
			
		||||
			case <-s.dequeuedSignal:
 | 
			
		||||
				// 收到出队信号,从头开始尝试入队
 | 
			
		||||
				timer.Stop()
 | 
			
		||||
				continue
 | 
			
		||||
			case <-ctx.Done():
 | 
			
		||||
				timer.Stop()
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/emirpasic/gods/maps/linkedhashmap"
 | 
			
		||||
	"mayfly-go/pkg/logx"
 | 
			
		||||
	"mayfly-go/pkg/utils/timex"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
@@ -32,7 +33,7 @@ type Job interface {
 | 
			
		||||
	Runnable(next NextFunc) bool
 | 
			
		||||
	GetDeadline() time.Time
 | 
			
		||||
	Schedule() bool
 | 
			
		||||
	Renew(job Job)
 | 
			
		||||
	Update(job Job)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type iterator[T Job] struct {
 | 
			
		||||
@@ -138,6 +139,7 @@ func NewRunner[T Job](maxRunning int) *Runner[T] {
 | 
			
		||||
	}
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer runner.wg.Done()
 | 
			
		||||
		timex.SleepWithContext(runner.context, time.Second*10)
 | 
			
		||||
		for runner.context.Err() == nil {
 | 
			
		||||
			job, ok := runner.delayQueue.Dequeue(ctx)
 | 
			
		||||
			if !ok {
 | 
			
		||||
@@ -277,7 +279,7 @@ func (r *Runner[T]) UpdateOrAdd(ctx context.Context, job T) error {
 | 
			
		||||
	defer r.mutex.Unlock()
 | 
			
		||||
 | 
			
		||||
	if old, ok := r.all[job.GetKey()]; ok {
 | 
			
		||||
		old.Renew(job)
 | 
			
		||||
		old.Update(job)
 | 
			
		||||
		job = old
 | 
			
		||||
	}
 | 
			
		||||
	r.schedule(ctx, job)
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ type testJob struct {
 | 
			
		||||
	deadline time.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *testJob) Renew(job Job) {
 | 
			
		||||
func (t *testJob) Update(_ Job) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *testJob) GetDeadline() time.Time {
 | 
			
		||||
@@ -82,6 +82,7 @@ func TestRunner_Close(t *testing.T) {
 | 
			
		||||
	}()
 | 
			
		||||
	waiting.Wait()
 | 
			
		||||
	timer := time.NewTimer(time.Microsecond * 10)
 | 
			
		||||
	defer timer.Stop()
 | 
			
		||||
	runner.Close()
 | 
			
		||||
	select {
 | 
			
		||||
	case <-timer.C:
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,10 @@ func (nt *NullTime) MarshalJSON() ([]byte, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SleepWithContext(ctx context.Context, d time.Duration) {
 | 
			
		||||
	ctx, cancel := context.WithTimeout(ctx, d)
 | 
			
		||||
	<-ctx.Done()
 | 
			
		||||
	cancel()
 | 
			
		||||
	timer := time.NewTimer(d)
 | 
			
		||||
	defer timer.Stop()
 | 
			
		||||
	select {
 | 
			
		||||
	case <-timer.C:
 | 
			
		||||
	case <-ctx.Done():
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user