feat(event): add event poll
This commit is contained in:
parent
bff937700e
commit
ac4fdd7309
|
@ -4,13 +4,11 @@ import (
|
||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
type eventType int8
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultEventState = eventType(iota) //默认情况下的状态
|
defaultEventState = int32(iota) //默认情况下的状态
|
||||||
waitEventState // 等待状态
|
waitEventState // 等待状态
|
||||||
workEventState //工作状态
|
workEventState //工作状态
|
||||||
closeEventState //事件关闭状态
|
closeEventState //事件关闭状态
|
||||||
)
|
)
|
||||||
|
|
||||||
type EventWorkFunc func() (interface{}, error)
|
type EventWorkFunc func() (interface{}, error)
|
||||||
|
@ -31,6 +29,5 @@ type ProduceInterface interface {
|
||||||
|
|
||||||
type ConsumerInterface interface {
|
type ConsumerInterface interface {
|
||||||
Receive(ctx context.Context) *event
|
Receive(ctx context.Context) *event
|
||||||
NewEvent(string) *event
|
|
||||||
Recovery(*event)
|
Recovery(*event)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package event
|
package event
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gitee.com/timedb/wheatCache/pkg/errorx"
|
"gitee.com/timedb/wheatCache/pkg/errorx"
|
||||||
|
@ -9,10 +9,18 @@ import (
|
||||||
|
|
||||||
// 事件 poll 降低 new 对象的频率
|
// 事件 poll 降低 new 对象的频率
|
||||||
type eventPoll struct {
|
type eventPoll struct {
|
||||||
poll chan *event
|
poll chan *event
|
||||||
|
maxSize int32
|
||||||
|
nowSize *int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *eventPoll) getEvent() *event {
|
func (e *eventPoll) getEvent() *event {
|
||||||
|
issSize := atomic.LoadInt32(e.nowSize)
|
||||||
|
if issSize < e.maxSize {
|
||||||
|
atomic.AddInt32(e.nowSize, 1)
|
||||||
|
return newEvent()
|
||||||
|
}
|
||||||
|
|
||||||
return <-e.poll
|
return <-e.poll
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,29 +31,40 @@ func (e *eventPoll) recovery(rEvent *event) {
|
||||||
|
|
||||||
func newEventPoll(maxSize int) *eventPoll {
|
func newEventPoll(maxSize int) *eventPoll {
|
||||||
return &eventPoll{
|
return &eventPoll{
|
||||||
poll: make(chan *event, maxSize),
|
poll: make(chan *event, maxSize),
|
||||||
|
maxSize: int32(maxSize),
|
||||||
|
nowSize: new(int32),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type event struct {
|
type event struct {
|
||||||
msgCtx map[string]interface{}
|
msgCtx map[string]interface{}
|
||||||
eventName string
|
eventName string
|
||||||
WorkTime time.Duration // 工作时间
|
|
||||||
msg map[string]string // 消息
|
msg map[string]string // 消息
|
||||||
waitResult chan interface{} // 等待返回
|
waitResult chan interface{} // 等待返回
|
||||||
err error
|
err error
|
||||||
ru sync.RWMutex
|
eventStatus *int32
|
||||||
muClose sync.Mutex //关闭锁
|
ttlManage *time.Timer
|
||||||
eventStatus eventType
|
}
|
||||||
|
|
||||||
|
func newEvent() *event {
|
||||||
|
status := defaultEventState
|
||||||
|
return &event{
|
||||||
|
eventStatus: &status,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *event) Reset() {
|
func (e *event) Reset() {
|
||||||
|
if e.ttlManage != nil {
|
||||||
|
e.ttlManage.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
e.err = nil
|
||||||
|
|
||||||
|
atomic.SwapInt32(e.eventStatus, defaultEventState)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *event) SetMsg(key string, val string) {
|
func (e *event) SetMsg(key string, val string) {
|
||||||
e.ru.Lock()
|
|
||||||
defer e.ru.Unlock()
|
|
||||||
if e.msg == nil {
|
if e.msg == nil {
|
||||||
e.msg = make(map[string]string)
|
e.msg = make(map[string]string)
|
||||||
}
|
}
|
||||||
|
@ -53,8 +72,6 @@ func (e *event) SetMsg(key string, val string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *event) GetMsg(key string) string {
|
func (e *event) GetMsg(key string) string {
|
||||||
e.ru.RLock()
|
|
||||||
defer e.ru.RUnlock()
|
|
||||||
return e.msg[key]
|
return e.msg[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,8 +81,6 @@ func (e *event) GetEventName() string {
|
||||||
|
|
||||||
// SetValue 写入 ctx 传递用参数
|
// SetValue 写入 ctx 传递用参数
|
||||||
func (e *event) SetValue(key string, value interface{}) {
|
func (e *event) SetValue(key string, value interface{}) {
|
||||||
e.ru.Lock()
|
|
||||||
defer e.ru.Unlock()
|
|
||||||
if e.msgCtx == nil {
|
if e.msgCtx == nil {
|
||||||
e.msgCtx = make(map[string]interface{})
|
e.msgCtx = make(map[string]interface{})
|
||||||
}
|
}
|
||||||
|
@ -73,76 +88,65 @@ func (e *event) SetValue(key string, value interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *event) GetValue(key string) (interface{}, bool) {
|
func (e *event) GetValue(key string) (interface{}, bool) {
|
||||||
e.ru.RLock()
|
|
||||||
defer e.ru.RUnlock()
|
|
||||||
val, ok := e.msgCtx[key]
|
val, ok := e.msgCtx[key]
|
||||||
return val, ok
|
return val, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitWaitEvent 初始化 wait event 必须调用才拥有等待特性
|
// InitWaitEvent 初始化 wait event 必须调用才拥有等待特性
|
||||||
func (e *event) InitWaitEvent() {
|
func (e *event) InitWaitEvent() {
|
||||||
e.muClose.Lock()
|
if e.waitResult == nil || len(e.waitResult) > 0 {
|
||||||
defer e.muClose.Unlock()
|
e.waitResult = make(chan interface{})
|
||||||
e.waitResult = make(chan interface{})
|
}
|
||||||
e.eventStatus = waitEventState
|
|
||||||
|
// 清理残留
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartWaitEvent 开始一个等待任务
|
// StartWaitEvent 开始一个等待任务
|
||||||
func (e *event) StartWaitEvent(ttl time.Duration) (interface{}, error) {
|
func (e *event) StartWaitEvent(ttl time.Duration) (interface{}, error) {
|
||||||
t := time.NewTimer(ttl)
|
e.ttlManage.Reset(ttl)
|
||||||
select {
|
|
||||||
case <-t.C:
|
for {
|
||||||
e.muClose.Lock()
|
select {
|
||||||
defer e.muClose.Unlock()
|
case <-e.ttlManage.C:
|
||||||
if e.eventStatus == workEventState {
|
if atomic.CompareAndSwapInt32(e.eventStatus, waitEventState, closeEventState) {
|
||||||
return <-e.waitResult, e.err
|
return nil, errorx.TimeOutErr()
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
|
||||||
|
case result := <-e.waitResult:
|
||||||
|
atomic.CompareAndSwapInt32(e.eventStatus, workEventState, closeEventState)
|
||||||
|
return result, e.err
|
||||||
}
|
}
|
||||||
|
|
||||||
e.eventStatus = closeEventState
|
|
||||||
return nil, errorx.TimeOutErr()
|
|
||||||
|
|
||||||
case result := <-e.waitResult:
|
|
||||||
return result, e.err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *event) ExecWorkAndSendResult(work EventWorkFunc) (interface{}, error) {
|
func (e *event) ExecWorkAndSendResult(work EventWorkFunc) (interface{}, error) {
|
||||||
e.muClose.Lock()
|
if !atomic.CompareAndSwapInt32(e.eventStatus, waitEventState, workEventState) {
|
||||||
defer e.muClose.Unlock()
|
|
||||||
if e.eventStatus != waitEventState {
|
|
||||||
return nil, errorx.New("not wait status, exec err")
|
return nil, errorx.New("not wait status, exec err")
|
||||||
}
|
}
|
||||||
|
|
||||||
e.eventStatus = workEventState
|
|
||||||
|
|
||||||
res, err := work()
|
res, err := work()
|
||||||
e.err = err
|
e.err = err
|
||||||
e.waitResult <- res
|
e.waitResult <- res
|
||||||
|
|
||||||
close(e.waitResult)
|
|
||||||
e.eventStatus = closeEventState
|
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *event) SetResultErr(err error) {
|
func (e *event) SetResultErr(err error) {
|
||||||
e.muClose.Lock()
|
if !atomic.CompareAndSwapInt32(e.eventStatus, waitEventState, workEventState) {
|
||||||
defer e.muClose.Unlock()
|
|
||||||
if e.eventStatus != waitEventState {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
e.eventStatus = workEventState
|
|
||||||
e.err = err
|
e.err = err
|
||||||
e.waitResult <- nil
|
e.waitResult <- nil
|
||||||
close(e.waitResult)
|
|
||||||
e.eventStatus = closeEventState
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEvent(eventName string) *event {
|
|
||||||
return &event{
|
|
||||||
eventName: eventName,
|
|
||||||
eventStatus: defaultEventState,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Driver struct {
|
type Driver struct {
|
||||||
|
@ -170,6 +174,7 @@ func (d *Driver) NewEvent(name string) *event {
|
||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 任何时候回收事件都应该由 最后使用者回收
|
||||||
func (d *Driver) Recovery(e *event) {
|
func (d *Driver) Recovery(e *event) {
|
||||||
d.poll.recovery(e)
|
d.poll.recovery(e)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue