nps/lib/file/file.go

182 lines
3.8 KiB
Go
Raw Normal View History

2019-02-09 09:07:47 +00:00
package file
import (
2019-03-29 05:31:11 +00:00
"encoding/json"
"errors"
"os"
2019-02-05 16:35:23 +00:00
"path/filepath"
2019-01-28 06:45:55 +00:00
"strings"
"sync"
2019-03-23 14:19:59 +00:00
"sync/atomic"
2019-08-10 03:15:25 +00:00
2020-01-08 13:57:14 +00:00
"ehang.io/nps/lib/common"
"ehang.io/nps/lib/rate"
)
2019-03-29 07:21:30 +00:00
func NewJsonDb(runPath string) *JsonDb {
return &JsonDb{
2019-03-29 05:31:11 +00:00
RunPath: runPath,
TaskFilePath: filepath.Join(runPath, "conf", "tasks.json"),
HostFilePath: filepath.Join(runPath, "conf", "hosts.json"),
ClientFilePath: filepath.Join(runPath, "conf", "clients.json"),
2019-02-09 09:07:47 +00:00
}
}
2019-03-29 07:21:30 +00:00
type JsonDb struct {
2019-03-23 14:19:59 +00:00
Tasks sync.Map
2019-03-29 07:21:30 +00:00
Hosts sync.Map
2019-03-23 14:19:59 +00:00
HostsTmp sync.Map
2019-03-29 07:21:30 +00:00
Clients sync.Map
RunPath string
ClientIncreaseId int32 //client increased id
TaskIncreaseId int32 //task increased id
HostIncreaseId int32 //host increased id
TaskFilePath string //task file path
HostFilePath string //host file path
ClientFilePath string //client file path
}
2019-03-29 07:21:30 +00:00
func (s *JsonDb) LoadTaskFromJsonFile() {
2019-03-29 05:31:11 +00:00
loadSyncMapFromFile(s.TaskFilePath, func(v string) {
var err error
post := new(Tunnel)
if json.Unmarshal([]byte(v), &post) != nil {
return
2019-02-12 19:54:00 +00:00
}
2019-03-29 05:31:11 +00:00
if post.Client, err = s.GetClient(post.Client.Id); err != nil {
return
}
2019-03-29 05:31:11 +00:00
s.Tasks.Store(post.Id, post)
if post.Id > int(s.TaskIncreaseId) {
s.TaskIncreaseId = int32(post.Id)
}
2019-03-23 14:19:59 +00:00
})
}
2019-03-29 07:21:30 +00:00
func (s *JsonDb) LoadClientFromJsonFile() {
2019-03-29 05:31:11 +00:00
loadSyncMapFromFile(s.ClientFilePath, func(v string) {
post := new(Client)
if json.Unmarshal([]byte(v), &post) != nil {
return
}
if post.RateLimit > 0 {
post.Rate = rate.NewRate(int64(post.RateLimit * 1024))
} else {
post.Rate = rate.NewRate(int64(2 << 23))
}
post.Rate.Start()
2019-03-29 07:21:30 +00:00
post.NowConn = 0
2019-03-29 05:31:11 +00:00
s.Clients.Store(post.Id, post)
if post.Id > int(s.ClientIncreaseId) {
s.ClientIncreaseId = int32(post.Id)
}
})
}
2019-03-29 07:21:30 +00:00
func (s *JsonDb) LoadHostFromJsonFile() {
2019-03-29 05:31:11 +00:00
loadSyncMapFromFile(s.HostFilePath, func(v string) {
var err error
post := new(Host)
if json.Unmarshal([]byte(v), &post) != nil {
return
2019-01-26 09:27:28 +00:00
}
2019-03-29 05:31:11 +00:00
if post.Client, err = s.GetClient(post.Client.Id); err != nil {
return
}
2019-03-29 05:31:11 +00:00
s.Hosts.Store(post.Id, post)
if post.Id > int(s.HostIncreaseId) {
s.HostIncreaseId = int32(post.Id)
}
2019-03-29 05:31:11 +00:00
})
2019-02-15 14:59:28 +00:00
}
2019-03-29 07:21:30 +00:00
func (s *JsonDb) GetClient(id int) (c *Client, err error) {
2019-03-23 14:19:59 +00:00
if v, ok := s.Clients.Load(id); ok {
c = v.(*Client)
return
}
2019-02-12 19:54:00 +00:00
err = errors.New("未找到客户端")
return
}
2019-03-29 05:31:11 +00:00
2019-03-29 07:21:30 +00:00
func (s *JsonDb) StoreHostToJsonFile() {
storeSyncMapToFile(s.Hosts, s.HostFilePath)
}
2019-02-09 09:07:47 +00:00
2019-03-29 07:21:30 +00:00
func (s *JsonDb) StoreTasksToJsonFile() {
storeSyncMapToFile(s.Tasks, s.TaskFilePath)
2019-02-15 14:59:28 +00:00
}
2019-03-29 07:21:30 +00:00
func (s *JsonDb) StoreClientsToJsonFile() {
storeSyncMapToFile(s.Clients, s.ClientFilePath)
2019-02-12 19:54:00 +00:00
}
2019-03-23 14:19:59 +00:00
2019-03-29 07:21:30 +00:00
func (s *JsonDb) GetClientId() int32 {
2019-03-29 05:31:11 +00:00
return atomic.AddInt32(&s.ClientIncreaseId, 1)
}
2019-03-29 07:21:30 +00:00
func (s *JsonDb) GetTaskId() int32 {
2019-03-29 05:31:11 +00:00
return atomic.AddInt32(&s.TaskIncreaseId, 1)
}
2019-03-29 07:21:30 +00:00
func (s *JsonDb) GetHostId() int32 {
2019-03-29 05:31:11 +00:00
return atomic.AddInt32(&s.HostIncreaseId, 1)
}
func loadSyncMapFromFile(filePath string, f func(value string)) {
b, err := common.ReadAllFromFile(filePath)
if err != nil {
panic(err)
}
for _, v := range strings.Split(string(b), "\n"+common.CONN_DATA_SEQ) {
f(v)
}
}
func storeSyncMapToFile(m sync.Map, filePath string) {
file, err := os.Create(filePath)
if err != nil {
2019-03-29 05:31:11 +00:00
panic(err)
}
2019-03-29 05:31:11 +00:00
defer file.Close()
m.Range(func(key, value interface{}) bool {
var b []byte
var err error
switch value.(type) {
case *Tunnel:
obj := value.(*Tunnel)
if obj.NoStore {
return true
}
b, err = json.Marshal(obj)
case *Host:
obj := value.(*Host)
if obj.NoStore {
return true
}
b, err = json.Marshal(obj)
case *Client:
obj := value.(*Client)
if obj.NoStore {
return true
}
b, err = json.Marshal(obj)
default:
2019-03-23 14:19:59 +00:00
return true
2019-02-12 19:54:00 +00:00
}
2019-03-29 05:31:11 +00:00
if err != nil {
return true
}
_, err = file.Write(b)
if err != nil {
panic(err)
}
2019-03-29 05:31:11 +00:00
_, err = file.Write([]byte("\n" + common.CONN_DATA_SEQ))
if err != nil {
2019-03-29 05:31:11 +00:00
panic(err)
}
2019-03-23 14:19:59 +00:00
return true
})
2020-02-11 11:54:16 +00:00
file.Sync()
}