This repository has been archived by the owner on Jul 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
room-manager.go
122 lines (107 loc) · 2.22 KB
/
room-manager.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
package api
import (
"context"
"sync"
"time"
)
// RoomManager is room manager.
type RoomManager struct {
rooms *sync.Map
}
// Store stores the room.
func (m *RoomManager) Store(room *Room) {
room.updated = time.Now()
key := room.ApplicationName + room.Version
roomMap, ok := m.rooms.Load(key)
if ok {
rooms, ok := roomMap.(*sync.Map)
if ok {
rooms.Store(room.RoomID, room)
return
}
}
rooms := &sync.Map{}
rooms.Store(room.RoomID, room)
m.rooms.Store(key, rooms)
}
// FindRoom returns the room.
func (m *RoomManager) FindRoom(roomID int) (room *Room) {
m.rooms.Range(func(_, value interface{}) bool {
rooms, ok := value.(*sync.Map)
if !ok {
return true
}
r, ok := rooms.Load(roomID)
if !ok {
return true
}
room, ok = r.(*Room)
return !ok
})
return
}
// Delete deletes the room.
func (m *RoomManager) Delete(roomID int) {
m.rooms.Range(func(_, value interface{}) bool {
rooms, ok := value.(*sync.Map)
if !ok {
return true
}
rooms.Delete(roomID)
return true
})
}
// Search returns returns all rooms with matching application name and version.
func (m *RoomManager) Search(name, version string) (rooms []*Room) {
v, ok := m.rooms.Load(name + version)
if !ok {
return
}
r, ok := v.(*sync.Map)
if !ok {
return
}
r.Range(func(_, value interface{}) bool {
room, ok := value.(*Room)
if !ok {
return true
}
if room.ApplicationName == name && room.Version == version {
rooms = append(rooms, room)
}
return true
})
return
}
// DeleteDeadRoomAtPeriodic removes dead rooms at regular intervals
func (m *RoomManager) DeleteDeadRoomAtPeriodic(ctx context.Context, duration time.Duration) {
ticker := time.NewTicker(duration)
for {
select {
case <-ticker.C:
var deadRoomIDs []int
m.rooms.Range(func(_, value interface{}) bool {
rooms, ok := value.(*sync.Map)
if !ok {
return true
}
rooms.Range(func(_, value interface{}) bool {
room, ok := value.(*Room)
if !ok {
return true
}
if time.Now().Sub(room.updated) > duration {
deadRoomIDs = append(deadRoomIDs, room.RoomID)
}
return true
})
return true
})
for _, id := range deadRoomIDs {
m.Delete(id)
}
case <-ctx.Done():
return
}
}
}