Fixed Syncthing folder status events and exec command.
[src/xds/xds-agent.git] / lib / agent / events.go
1 package agent
2
3 import (
4         "fmt"
5         "time"
6 )
7
8 // Events constants
9 const (
10         // EventTypePrefix Used as event prefix
11         EventTypePrefix = "event:" // following by event type
12
13         // Supported Events type
14         EVTAll           = "all"
15         EVTServerConfig  = "server-config"        // data type ServerCfg
16         EVTProjectAdd    = "project-add"          // data type ProjectConfig
17         EVTProjectDelete = "project-delete"       // data type ProjectConfig
18         EVTProjectChange = "project-state-change" // data type ProjectConfig
19 )
20
21 var _EVTAllList = []string{
22         EVTServerConfig,
23         EVTProjectAdd,
24         EVTProjectDelete,
25         EVTProjectChange,
26 }
27
28 // EventMsg Message send
29 type EventMsg struct {
30         Time string      `json:"time"`
31         Type string      `json:"type"`
32         Data interface{} `json:"data"`
33 }
34
35 type EventDef struct {
36         sids map[string]int
37 }
38
39 type Events struct {
40         *Context
41         eventsMap map[string]*EventDef
42 }
43
44 // NewEvents creates an instance of Events
45 func NewEvents(ctx *Context) *Events {
46         evMap := make(map[string]*EventDef)
47         for _, ev := range _EVTAllList {
48                 evMap[ev] = &EventDef{
49                         sids: make(map[string]int),
50                 }
51         }
52         return &Events{
53                 Context:   ctx,
54                 eventsMap: evMap,
55         }
56 }
57
58 // GetList returns the list of all supported events
59 func (e *Events) GetList() []string {
60         return _EVTAllList
61 }
62
63 // Register Used by a client/session to register to a specific (or all) event(s)
64 func (e *Events) Register(evName, sessionID string) error {
65         evs := _EVTAllList
66         if evName != EVTAll {
67                 if _, ok := e.eventsMap[evName]; !ok {
68                         return fmt.Errorf("Unsupported event type name")
69                 }
70                 evs = []string{evName}
71         }
72         for _, ev := range evs {
73                 e.eventsMap[ev].sids[sessionID]++
74         }
75         return nil
76 }
77
78 // UnRegister Used by a client/session to unregister event(s)
79 func (e *Events) UnRegister(evName, sessionID string) error {
80         evs := _EVTAllList
81         if evName != EVTAll {
82                 if _, ok := e.eventsMap[evName]; !ok {
83                         return fmt.Errorf("Unsupported event type name")
84                 }
85                 evs = []string{evName}
86         }
87         for _, ev := range evs {
88                 if _, exist := e.eventsMap[ev].sids[sessionID]; exist {
89                         delete(e.eventsMap[ev].sids, sessionID)
90                         break
91                 }
92         }
93         return nil
94 }
95
96 // Emit Used to manually emit an event
97 func (e *Events) Emit(evName string, data interface{}) error {
98         var firstErr error
99
100         if _, ok := e.eventsMap[evName]; !ok {
101                 return fmt.Errorf("Unsupported event type")
102         }
103
104         if e.LogLevelSilly {
105                 e.Log.Debugf("Emit Event %s: %v", evName, data)
106         }
107
108         firstErr = nil
109         evm := e.eventsMap[evName]
110         for sid := range evm.sids {
111                 so := e.webServer.sessions.IOSocketGet(sid)
112                 if so == nil {
113                         if firstErr == nil {
114                                 firstErr = fmt.Errorf("IOSocketGet return nil")
115                         }
116                         continue
117                 }
118                 msg := EventMsg{
119                         Time: time.Now().String(),
120                         Type: evName,
121                         Data: data,
122                 }
123                 if err := (*so).Emit(EventTypePrefix+evName, msg); err != nil {
124                         e.Log.Errorf("WS Emit %v error : %v", EventTypePrefix+evName, err)
125                         if firstErr == nil {
126                                 firstErr = err
127                         }
128                 }
129         }
130
131         return firstErr
132 }