-
Notifications
You must be signed in to change notification settings - Fork 0
/
event.go
111 lines (97 loc) · 2.04 KB
/
event.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package vade
import (
"math/rand"
"regexp"
"sync"
"time"
"github.com/derry6/vade-go/pkg/log"
"github.com/derry6/vade-go/source"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
// Event property event
type Event = source.Event
// Event actions
var (
Created = source.Created
Updated = source.Updated
Deleted = source.Deleted
)
// EventHandler 事件处理
type EventHandler interface {
OnPropertyChange(events []*Event)
}
type wrapper struct {
id int64
pattern string
handler EventHandler
}
// dispatcher event dispatcher
type dispatcher struct {
mutex sync.RWMutex
handlers map[int64]*wrapper
}
func newDispatcher() *dispatcher {
return &dispatcher{
mutex: sync.RWMutex{},
handlers: make(map[int64]*wrapper),
}
}
func (d *dispatcher) Unwatch(id int64) {
d.mutex.Lock()
defer d.mutex.Unlock()
delete(d.handlers, id)
}
func (d *dispatcher) Watch(pattern string, handler EventHandler) (nextId int64) {
d.mutex.Lock()
defer d.mutex.Unlock()
for id, hdr := range d.handlers {
if hdr.pattern == pattern && handler == hdr.handler {
return id
}
}
for {
nextId = rand.Int63()
if _, ok := d.handlers[nextId]; ok {
continue
}
d.handlers[nextId] = &wrapper{
id: nextId,
pattern: pattern,
handler: handler,
}
break
}
return nextId
}
func (d *dispatcher) handlersOf(key string) (hdrs []EventHandler) {
d.mutex.RLock()
defer d.mutex.RUnlock()
for _, w := range d.handlers {
if ok, _ := regexp.MatchString(w.pattern, key); ok {
hdrs = append(hdrs, w.handler)
}
}
return hdrs
}
func (d *dispatcher) Dispatch(events []*Event) {
log.Get().Debugf("dispatch events: %v", events)
grpEvents := map[EventHandler][]*Event{}
for _, ev := range events {
handlers := d.handlersOf(ev.Key)
for _, handler := range handlers {
if s := grpEvents[handler]; s != nil {
grpEvents[handler] = append(grpEvents[handler], ev)
} else {
grpEvents[handler] = []*Event{ev}
}
}
}
for handler, _events := range grpEvents {
if handler == nil {
continue
}
handler.OnPropertyChange(_events)
}
}