-
Notifications
You must be signed in to change notification settings - Fork 2
/
hub.go
112 lines (96 loc) · 2.55 KB
/
hub.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
package main
import (
"encoding/json"
"log"
)
// Hub maintains a set of active clients and broadcasts messages to the clients
type Hub struct {
// Map of clients
clients map[*Client]struct{}
// Inbound messages from the clients
broadcast chan Message
// registers a client from the hub
register chan *Client
// unregister a client from the hub
unregister chan *Client
}
func (hub *Hub) countConnections() int {
return len(hub.clients)
}
func processMessage(message *Message) bool {
switch message.Type {
case NEW:
// You can not create a talk for a previous meeting
wednesday := nextWednesday()
if message.New.Week == "" {
message.New.Week = wednesday
} else if isPast(wednesday, message.New.Week) {
return false
}
// Validate talk type
if message.New.Talktype > 4 {
return false
}
// Validate talk description
if message.New.Description == "" {
return false
}
// Validate talk name
if message.New.Name == "" {
return false
}
message.New.ID = talks.Create(message.New.Name, message.New.Talktype, message.New.Description, message.New.Week)
// Update the message's description to be parsed as markdown
message.New.Description = string(markDownerSafe(message.New.Description))
return true
case HIDE:
// During meetings we hide talks instead of deleting them
if duringMeeting() {
log.Println("[INFO] Hide talk {", message.Hide.ID, "}")
talks.Hide(message.Hide.ID)
} else {
log.Println("[INFO] Delete talk {", message.Hide.ID, "}")
talks.Delete(message.Hide.ID)
}
return true
case DELETE:
log.Println("[INFO] Delete talk {", message.Hide.ID, "}")
talks.Delete(message.Hide.ID)
return true
default:
return false
}
}
func (hub *Hub) run() {
for {
select {
case client := <-hub.register:
// registers a client
hub.clients[client] = struct{}{}
case client := <-hub.unregister:
// unregister a client
delete(hub.clients, client)
close(client.send)
case message := <-hub.broadcast:
log.Println("[INFO] Broadcast message:", message)
// broadcasts the message to all clients (including the one that sent the message)
if !processMessage(&message) {
log.Println("[WARN] Invalid message")
}
// Serialize message into a byte slice
bytes, err := json.Marshal(message)
if err != nil {
log.Println("[WARN] failed to marshal", err)
}
for client := range hub.clients {
select {
case client.send <- bytes:
default:
// if sending to a client blocks we drop the client
close(client.send)
delete(hub.clients, client)
}
}
}
}
}