forked from tada-team/nane
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstorage.go
113 lines (90 loc) · 2.01 KB
/
storage.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
package main
import (
"container/ring"
"sort"
"strings"
"sync"
"time"
"github.com/gorilla/websocket"
"github.com/tada-team/nane/nane"
)
type Session struct {
nane.Sender
conn *websocket.Conn
}
type Room struct {
nane.Room
messages *ring.Ring
mux *sync.Mutex
}
var (
roomsMap map[string]*Room
roomsMux sync.Mutex
sessions = make(map[*websocket.Conn]Session)
)
func reset() {
roomsMap = make(map[string]*Room)
}
func init() {
reset()
}
type contentError string
func (e contentError) Error() string {
return string(e)
}
func addMessage(sender nane.Sender, msg *nane.Message) error {
msg.Text = truncateString(strings.TrimSpace(msg.Text), settings.GetMaxMessageLength())
if msg.Text == "" {
return contentError("text required")
}
msg.Room = truncateString(strings.TrimSpace(msg.Room), settings.GetMaxRoomTitleLength())
if msg.Room == "" {
return contentError("room required")
}
room := getOrCreateRoom(msg.Room)
room.mux.Lock()
defer room.mux.Unlock()
msg.Room = room.Name
msg.Created = time.Now()
msg.Sender = sender
room.LastMessage = msg
room.messages.Value = *msg
room.messages = room.messages.Next()
return nil
}
func (room *Room) getMessages() []nane.Message {
var result []nane.Message
room.messages.Do(func(i interface{}) {
if i != nil {
result = append(result, i.(nane.Message))
}
})
sort.Slice(result, func(i, j int) bool {
return result[i].Created.Before(result[j].Created)
})
return result
}
func getRooms() []nane.Room {
result := make([]nane.Room, 0, len(roomsMap))
for _, room := range roomsMap {
result = append(result, room.Room)
}
return result
}
func getRoom(name string) *Room {
return roomsMap[normalizeRoomName(name)]
}
func getOrCreateRoom(name string) *Room {
roomsMux.Lock()
defer roomsMux.Unlock()
room := getRoom(name)
if room == nil {
room = &Room{
Room: nane.Room{Name: name},
messages: ring.New(settings.GetMaxMessagesInRoom()),
mux: new(sync.Mutex),
}
roomsMap[normalizeRoomName(name)] = room
}
return room
}