wheat-cache/pkg/event/driver.go

190 lines
3.7 KiB
Go
Raw Normal View History

2021-09-23 11:05:51 +08:00
package event
import (
2021-10-26 14:39:34 +08:00
"sync/atomic"
2021-09-23 11:05:51 +08:00
"time"
2021-09-28 20:55:09 +08:00
2021-11-02 14:45:08 +08:00
"gitee.com/wheat-os/wheatCache/pkg/errorx"
2021-09-23 11:05:51 +08:00
)
2021-10-26 09:29:39 +08:00
// 事件 poll 降低 new 对象的频率
type eventPoll struct {
2021-10-26 14:39:34 +08:00
poll chan *event
maxSize int32
nowSize *int32
2021-10-26 09:29:39 +08:00
}
func (e *eventPoll) getEvent() *event {
2021-10-26 14:39:34 +08:00
issSize := atomic.LoadInt32(e.nowSize)
if issSize < e.maxSize {
atomic.AddInt32(e.nowSize, 1)
return newEvent()
}
2021-10-26 09:29:39 +08:00
return <-e.poll
}
func (e *eventPoll) recovery(rEvent *event) {
rEvent.Reset()
e.poll <- rEvent
}
func newEventPoll(maxSize int) *eventPoll {
return &eventPoll{
2021-10-26 14:39:34 +08:00
poll: make(chan *event, maxSize),
maxSize: int32(maxSize),
nowSize: new(int32),
2021-10-26 09:29:39 +08:00
}
}
2021-09-23 11:05:51 +08:00
2021-10-26 09:29:39 +08:00
type event struct {
2021-09-23 11:05:51 +08:00
msgCtx map[string]interface{}
eventName string
msg map[string]string // 消息
waitResult chan interface{} // 等待返回
2021-09-28 20:55:09 +08:00
err error
2021-10-26 14:39:34 +08:00
eventStatus *int32
ttlManage *time.Timer
}
func newEvent() *event {
status := defaultEventState
return &event{
eventStatus: &status,
}
2021-09-23 11:05:51 +08:00
}
2021-10-26 09:29:39 +08:00
func (e *event) Reset() {
2021-10-26 14:39:34 +08:00
if e.ttlManage != nil {
e.ttlManage.Stop()
}
e.err = nil
2021-10-26 09:29:39 +08:00
2021-10-26 14:39:34 +08:00
atomic.SwapInt32(e.eventStatus, defaultEventState)
2021-10-26 09:29:39 +08:00
}
func (e *event) SetMsg(key string, val string) {
2021-09-23 11:05:51 +08:00
if e.msg == nil {
e.msg = make(map[string]string)
}
e.msg[key] = val
}
2021-10-26 09:29:39 +08:00
func (e *event) GetMsg(key string) string {
2021-09-23 11:05:51 +08:00
return e.msg[key]
}
2021-10-26 09:29:39 +08:00
func (e *event) GetEventName() string {
2021-09-28 20:55:09 +08:00
return e.eventName
}
// SetValue 写入 ctx 传递用参数
2021-10-26 09:29:39 +08:00
func (e *event) SetValue(key string, value interface{}) {
2021-09-23 11:05:51 +08:00
if e.msgCtx == nil {
e.msgCtx = make(map[string]interface{})
}
e.msgCtx[key] = value
}
2021-10-26 09:29:39 +08:00
func (e *event) GetValue(key string) (interface{}, bool) {
2021-09-23 11:05:51 +08:00
val, ok := e.msgCtx[key]
return val, ok
}
2021-09-28 20:55:09 +08:00
// InitWaitEvent 初始化 wait event 必须调用才拥有等待特性
2021-10-26 09:29:39 +08:00
func (e *event) InitWaitEvent() {
2021-10-26 14:39:34 +08:00
if e.waitResult == nil || len(e.waitResult) > 0 {
e.waitResult = make(chan interface{})
}
// 清理残留
if e.ttlManage == nil {
e.ttlManage = time.NewTimer(0)
}
e.ttlManage.Stop()
if len(e.ttlManage.C) > 0 {
<-e.ttlManage.C
}
atomic.CompareAndSwapInt32(e.eventStatus, defaultEventState, waitEventState)
2021-09-28 20:55:09 +08:00
}
2021-09-23 11:05:51 +08:00
2021-09-28 20:55:09 +08:00
// StartWaitEvent 开始一个等待任务
2021-10-26 09:29:39 +08:00
func (e *event) StartWaitEvent(ttl time.Duration) (interface{}, error) {
2021-10-26 14:39:34 +08:00
e.ttlManage.Reset(ttl)
for {
select {
case <-e.ttlManage.C:
if atomic.CompareAndSwapInt32(e.eventStatus, waitEventState, closeEventState) {
return nil, errorx.TimeOutErr()
}
continue
case result := <-e.waitResult:
atomic.CompareAndSwapInt32(e.eventStatus, workEventState, closeEventState)
return result, e.err
2021-09-28 20:55:09 +08:00
}
}
2021-09-23 11:05:51 +08:00
}
2021-10-26 09:29:39 +08:00
func (e *event) ExecWorkAndSendResult(work EventWorkFunc) (interface{}, error) {
2021-10-26 14:39:34 +08:00
if !atomic.CompareAndSwapInt32(e.eventStatus, waitEventState, workEventState) {
2021-09-28 20:55:09 +08:00
return nil, errorx.New("not wait status, exec err")
2021-09-23 11:05:51 +08:00
}
2021-09-28 20:55:09 +08:00
res, err := work()
e.err = err
2021-10-07 16:30:23 +08:00
e.waitResult <- res
2021-09-28 20:55:09 +08:00
return res, err
2021-09-23 11:05:51 +08:00
}
2021-10-26 09:29:39 +08:00
func (e *event) SetResultErr(err error) {
2021-10-26 14:39:34 +08:00
if !atomic.CompareAndSwapInt32(e.eventStatus, waitEventState, workEventState) {
2021-10-07 16:30:23 +08:00
return
}
e.err = err
e.waitResult <- nil
2021-09-23 11:05:51 +08:00
}
type Driver struct {
maxQueueSize int
2021-10-26 09:29:39 +08:00
queue chan *event
poll *eventPoll
2021-09-23 11:05:51 +08:00
}
// Get 获取驱动
2021-10-26 09:29:39 +08:00
func (d *Driver) Get() *event {
2021-09-23 11:05:51 +08:00
return <-d.queue
}
2021-10-26 09:29:39 +08:00
func (d *Driver) Put(event *event) {
2021-09-23 11:05:51 +08:00
d.queue <- event
}
func (d *Driver) GetLength() int {
return len(d.queue)
2021-10-09 10:35:03 +08:00
}
2021-10-26 09:29:39 +08:00
func (d *Driver) NewEvent(name string) *event {
event := d.poll.getEvent()
event.eventName = name
return event
}
2021-10-26 14:39:34 +08:00
// 任何时候回收事件都应该由 最后使用者回收
2021-10-26 09:29:39 +08:00
func (d *Driver) Recovery(e *event) {
d.poll.recovery(e)
}
2021-09-23 11:05:51 +08:00
// NewDriver 新建 Driver
func NewDriver(maxSize int) DriverInterface {
return &Driver{
maxQueueSize: maxSize,
2021-10-26 09:29:39 +08:00
queue: make(chan *event, maxSize),
poll: newEventPoll(maxSize),
2021-09-23 11:05:51 +08:00
}
}