forked from misakwa/gozyre
-
Notifications
You must be signed in to change notification settings - Fork 0
/
event.go
129 lines (106 loc) · 3.49 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package gozyre
/*
#include "zyre.h"
*/
import "C"
import (
"unsafe"
)
// EventType describes network events
type EventType string
const (
// JoinEvent indicates a node has joined a specific group
JoinEvent EventType = "JOIN"
// ExitEvent indicates a node has left the network
ExitEvent = "EXIT"
// EnterEvent indicates a node hash entered the network
EnterEvent = "ENTER"
// LeaveEvent indicates a peer has left a specific group
LeaveEvent = "LEAVE"
// StopEvent indicates that a node will go away
StopEvent = "STOP"
// EvasiveEvent indicates a node is being quiet for too long
EvasiveEvent = "EVASIVE"
// WhisperEvent indicates a peer has sent a message to this node
WhisperEvent = "WHISPER"
// ShoutEvent indicates a peer has sent a message to a group
ShoutEvent = "SHOUT"
// UnknownEvent indicates a message that is unsupported or unknown
UnknownEvent = "UNKNOWN"
)
// Event describes a network event
type Event struct {
czyreEvent *C.struct__zyre_event_t
}
// NewEvent creates a new Event object
func NewEvent(node *Zyre) (*Event, error) {
cevent := C.zyre_event_new(node.czyre)
if cevent == nil {
return nil, ErrNodeInterrupted
}
return &Event{czyreEvent: cevent}, nil
}
// Type returns the event type
func (ev *Event) Type() EventType {
evt := C.GoString(C.zyre_event_type(ev.czyreEvent))
switch evt {
case "ENTER":
return EnterEvent
case "JOIN":
return JoinEvent
case "EXIT":
return ExitEvent
case "LEAVE":
return LeaveEvent
case "STOP":
return StopEvent
case "EVASIVE":
return EvasiveEvent
case "WHISPER":
return WhisperEvent
case "SHOUT":
return ShoutEvent
default:
return UnknownEvent
}
}
// UUID returns the uuid of the peer responsible for this event
func (ev *Event) UUID() string { return C.GoString(C.zyre_event_peer_uuid(ev.czyreEvent)) }
// Peer returns the name of the peer sending the event
func (ev *Event) Peer() string { return C.GoString(C.zyre_event_peer_name(ev.czyreEvent)) }
// Group returns the group name for a ShoutEvent
func (ev *Event) Group() string { return C.GoString(C.zyre_event_group(ev.czyreEvent)) }
// Address returns the address of the sending peer ip address
func (ev *Event) Address() string { return C.GoString(C.zyre_event_peer_addr(ev.czyreEvent)) }
// Headers returns the event headers. These are the headers from the node that
// initiated this event.
// XXX: Do we need to lock the headers? The underlying implementation uses a
// cursor to iterate through the items and may introduce race conditions.
func (ev *Event) Headers() map[string]string {
czev := ev.czyreEvent
if (czev == nil) {
return nil
}
czhdr := C.zyre_event_headers(czev)
if (czhdr == nil) {
return nil
}
return zHashToMap(czhdr, false)
}
// Header returns the header value from the header name
func (ev *Event) Header(name string) string {
hname := C.CString(name)
defer C.free(unsafe.Pointer(hname))
return C.GoString(C.zyre_event_header(ev.czyreEvent, hname))
}
// Message returns the frames of data from the message content, each frame as a byte slice
// XXX: Do we need to lock the channel so that only one consumer can call it?
// The underlying implementation iterates through the message frames using a
// cursor and can introduce race conditions.
func (ev *Event) Message() <-chan []byte { return zMsgToBytes(C.zyre_event_msg(ev.czyreEvent)) }
// Destroy removes and frees up the event object memory. The event should not
// be used after callling this method.
func (ev *Event) Destroy() {
C.zyre_event_destroy(&ev.czyreEvent)
ev.czyreEvent = nil
}