JCC-CSScheduler/manager/internal/jobmgr/event_set.go

91 lines
2.1 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 jobmgr
import (
"context"
"errors"
"sync"
"gitlink.org.cn/cloudream/common/pkgs/future"
"gitlink.org.cn/cloudream/common/utils/lo2"
)
type EventWaitCondition func(evt Event) bool
var ErrJobCancelled = errors.New("job cancelled")
type Event interface {
Noop()
}
type EventWaiter struct {
condition EventWaitCondition
future *future.SetValueFuture[Event]
}
type EventSet struct {
events []Event
waiters []EventWaiter
lock sync.Mutex
}
func NewEventSet() EventSet {
return EventSet{}
}
// Post 函数用于向事件集合中发布一个事件。
// 如果有等待该事件的协程,会唤醒它们并将事件传递给它们。
// 参数:
//
// evt Event - 需要发布的事件对象。
func (s *EventSet) Post(evt Event) {
s.lock.Lock() // 加锁保护事件集合
defer s.lock.Unlock() // 确保在函数结束时释放锁
// 遍历等待者列表查找匹配的等待者。如果找到从列表中移除并设置其future的值。
used := false // 标记当前事件是否已被使用(即是否唤醒了某个等待者)
for i, waiter := range s.waiters {
if waiter.condition(evt) { // 检查当前事件是否满足等待条件
s.waiters = lo2.RemoveAt(s.waiters, i) // 从等待者列表中移除当前等待者
waiter.future.SetValue(evt) // 设置等待者的future值为当前事件
used = true // 标记事件已被使用
}
}
// 如果没有匹配的等待者,则将事件添加到事件列表中。
if !used {
s.events = append(s.events, evt)
}
}
func (s *EventSet) Wait(ctx context.Context, cond EventWaitCondition) (Event, bool) {
s.lock.Lock()
//defer s.lock.Unlock()
// 一个等待者只能等待一个事件
for i, evt := range s.events {
if cond(evt) {
s.events = lo2.RemoveAt(s.events, i)
s.lock.Unlock()
return evt, true
}
}
fut := future.NewSetValue[Event]()
waiter := EventWaiter{
condition: cond,
future: fut,
}
//s.events = append(s.events, waiter)
s.waiters = append(s.waiters, waiter)
s.lock.Unlock()
val, err := fut.WaitValue(ctx)
if err != nil {
return nil, false
}
return val, true
}