aboutsummaryrefslogtreecommitdiffstats
path: root/lib/agent/events.go
blob: 24efc5a192a35814679d649478c6192ccc83c97c (plain)
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package agent

import (
	"fmt"
	"time"
)

// Events constants
const (
	// EventTypePrefix Used as event prefix
	EventTypePrefix = "event:" // following by event type

	// Supported Events type
	EVTAll           = "all"
	EVTServerConfig  = "server-config"        // data type ServerCfg
	EVTProjectAdd    = "project-add"          // data type ProjectConfig
	EVTProjectDelete = "project-delete"       // data type ProjectConfig
	EVTProjectChange = "project-state-change" // data type ProjectConfig
)

var EVTAllList = []string{
	EVTServerConfig,
	EVTProjectAdd,
	EVTProjectDelete,
	EVTProjectChange,
}

// EventMsg Message send
type EventMsg struct {
	Time string      `json:"time"`
	Type string      `json:"type"`
	Data interface{} `json:"data"`
}

type EventDef struct {
	// SEB cbs  []EventsCB
	sids map[string]int
}

type Events struct {
	*Context
	eventsMap map[string]*EventDef
}

// NewEvents creates an instance of Events
func NewEvents(ctx *Context) *Events {
	evMap := make(map[string]*EventDef)
	for _, ev := range EVTAllList {
		evMap[ev] = &EventDef{
			sids: make(map[string]int),
		}
	}
	return &Events{
		Context:   ctx,
		eventsMap: evMap,
	}
}

// GetList returns the list of all supported events
func (e *Events) GetList() []string {
	return EVTAllList
}

// Register Used by a client/session to register to a specific (or all) event(s)
func (e *Events) Register(evName, sessionID string) error {
	evs := EVTAllList
	if evName != EVTAll {
		if _, ok := e.eventsMap[evName]; !ok {
			return fmt.Errorf("Unsupported event type name")
		}
		evs = []string{evName}
	}
	for _, ev := range evs {
		e.eventsMap[ev].sids[sessionID]++
	}
	return nil
}

// UnRegister Used by a client/session to unregister event(s)
func (e *Events) UnRegister(evName, sessionID string) error {
	evs := EVTAllList
	if evName != EVTAll {
		if _, ok := e.eventsMap[evName]; !ok {
			return fmt.Errorf("Unsupported event type name")
		}
		evs = []string{evName}
	}
	for _, ev := range evs {
		if _, exist := e.eventsMap[ev].sids[sessionID]; exist {
			delete(e.eventsMap[ev].sids, sessionID)
			break
		}
	}
	return nil
}

// Emit Used to manually emit an event
func (e *Events) Emit(evName string, data interface{}) error {
	var firstErr error

	if _, ok := e.eventsMap[evName]; !ok {
		return fmt.Errorf("Unsupported event type")
	}

	e.Log.Debugf("Emit Event %s: %v", evName, data)

	firstErr = nil
	evm := e.eventsMap[evName]
	for sid := range evm.sids {
		so := e.webServer.sessions.IOSocketGet(sid)
		if so == nil {
			if firstErr == nil {
				firstErr = fmt.Errorf("IOSocketGet return nil")
			}
			continue
		}
		msg := EventMsg{
			Time: time.Now().String(),
			Type: evName,
			Data: data,
		}
		if err := (*so).Emit(EventTypePrefix+evName, msg); err != nil {
			e.Log.Errorf("WS Emit %v error : %v", EventTypePrefix+evName, err)
			if firstErr == nil {
				firstErr = err
			}
		}
	}

	return firstErr
}