forked from hidu/api-front
-
Notifications
You must be signed in to change notification settings - Fork 0
/
api_counter.go
93 lines (84 loc) · 1.78 KB
/
api_counter.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
package proxy
import (
"encoding/json"
"io/ioutil"
"log"
"sync"
"time"
)
// Counter counter for server
type Counter struct {
Pv map[string]uint64 `json:"pv"`
rw sync.RWMutex
TotalPv uint64 `json:"total"`
filePath string
lastMod time.Time
lastWrite time.Time
}
func newCounter(apiServer *APIServer) *Counter {
jsonPath := apiServer.getConfDir() + "_counter.json"
var counter *Counter
err := LoadJSONFile(jsonPath, &counter)
if err != nil {
log.Println("[warning]load counter failed:", jsonPath, ",err:", err)
counter = new(Counter)
}
counter.filePath = jsonPath
if counter.Pv == nil {
counter.Pv = make(map[string]uint64)
}
counter.lastMod = time.Now()
counter.lastWrite = counter.lastMod
go counter.AutoSave(60)
return counter
}
func (c *Counter) pvInc(name string) uint64 {
c.rw.Lock()
defer c.rw.Unlock()
if _, has := c.Pv[name]; !has {
c.Pv[name] = 0
}
c.Pv[name]++
c.TotalPv++
c.lastMod = time.Now()
return c.TotalPv
}
// GetPv get pv num
func (c *Counter) GetPv(name string) uint64 {
c.rw.RLock()
defer c.rw.RUnlock()
if v, has := c.Pv[name]; has {
return v
}
return 0
}
// GetTotalPv total pv
func (c *Counter) GetTotalPv() uint64 {
c.rw.RLock()
defer c.rw.RUnlock()
return c.TotalPv
}
// AutoSave auto save to file
func (c *Counter) AutoSave(sec int64) {
t := time.NewTicker(time.Duration(sec) * time.Second)
for {
select {
case <-t.C:
if c.lastWrite.UnixNano() < c.lastMod.UnixNano() {
c.SaveFile()
}
}
}
}
// SaveFile save to file
func (c *Counter) SaveFile() error {
log.Println("[info]save counter file:", c.filePath)
c.rw.RLock()
defer c.rw.RUnlock()
data, err := json.MarshalIndent(c, "", " ")
if err != nil {
return err
}
c.lastWrite = time.Now()
return ioutil.WriteFile(c.filePath, data, 0666)
}