-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.go
127 lines (106 loc) · 2.58 KB
/
server.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
package redis
import (
"bufio"
"encoding/json"
"os"
"sync"
"sync/atomic"
)
var (
lastPublishCount uint64 = 0
DefaultDumpFileName = "../redisServer.dump.json"
fileWriteMu sync.Mutex
)
// Save the DB in background. The OK code is immediately returned. Redis forks, the parent
// continues to serve the clients, the child saves the DB on disk then exits. A client my
// be able to check if the operation succeeded using the LASTSAVE command.
// Please refer to the persistence documentation for detailed information.
//
// Return value
// Simple string reply
func BgSave(fileName string, complete chan bool) string {
pubCount := atomic.LoadUint64(&publishCount)
if pubCount > atomic.LoadUint64(&lastPublishCount) {
atomic.StoreUint64(&lastPublishCount, pubCount)
go func() {
fileWriteMu.Lock()
defer fileWriteMu.Unlock()
fo, _ := os.Create(fileName)
defer fo.Close()
w := bufio.NewWriter(fo)
// TODO: Lock around each key (checking existence) instead of around the whole
// hash so that other operations may sneak in.
allMaps := make(map[string]map[string]string)
hashesMu.RLock()
for key, hash := range allHashes {
allMaps[key] = hash.ToMap()
}
hashesMu.RUnlock()
b1, err := json.MarshalIndent(&allMaps, "", " ")
if err != nil {
println(err.Error())
return
}
w.Write(b1)
listsMu.RLock()
b2, err := json.MarshalIndent(&allLists, "", " ")
listsMu.RUnlock()
if err != nil {
println(err.Error())
return
}
w.Write(b2)
setsMu.RLock()
b3, err := json.MarshalIndent(&allSets, "", " ")
setsMu.RUnlock()
if err != nil {
println(err.Error())
return
}
w.Write(b3)
stringsMu.RLock()
b4, err := json.MarshalIndent(&allStrings, "", " ")
stringsMu.RUnlock()
if err != nil {
println(err.Error())
return
}
w.Write(b4)
w.Flush()
if complete != nil {
complete <- true
}
}()
}
return "OK"
}
//// Load any backup before doing anything else.
//
func InitDB(fileName string) {
if fileName != "" {
fileWriteMu.Lock()
defer fileWriteMu.Unlock()
fo, _ := os.Open(fileName)
defer fo.Close()
r := bufio.NewReader(fo)
dec := json.NewDecoder(r)
allMaps := make(map[string]map[string]string)
dec.Decode(&allMaps)
hashesMu.Lock()
for key, aMap := range allMaps {
hash := NewHash()
hash.m = aMap
allHashes[key] = hash
}
hashesMu.Unlock()
listsMu.Lock()
dec.Decode(&allLists)
listsMu.Unlock()
setsMu.Lock()
dec.Decode(&allSets)
setsMu.Unlock()
stringsMu.Lock()
dec.Decode(&allStrings)
stringsMu.Unlock()
}
}