diff --git a/Makefile b/Makefile index a57ed2a..cea530a 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ build_static: build: clean sh script/build.sh $(VERSION) -test: redis_test boltdb_test memory_test config_test +test: redis_test boltdb_test memory_test buntdb_test leveldb_test config_test go test -v -cover ./gorush/... redis_test: init @@ -55,6 +55,9 @@ memory_test: init buntdb_test: init go test -v -cover ./storage/buntdb/... +leveldb_test: init + go test -v -cover ./storage/leveldb/... + config_test: init go test -v -cover ./config/... diff --git a/config/config.go b/config/config.go index 104bed3..ce68b58 100644 --- a/config/config.go +++ b/config/config.go @@ -65,10 +65,11 @@ type SectionLog struct { // SectionStat is sub seciont of config. type SectionStat struct { - Engine string `yaml:"engine"` - Redis SectionRedis `yaml:"redis"` - BoltDB SectionBoltDB `yaml:"boltdb"` - BuntDB SectionBuntDB `yaml:"buntdb"` + Engine string `yaml:"engine"` + Redis SectionRedis `yaml:"redis"` + BoltDB SectionBoltDB `yaml:"boltdb"` + BuntDB SectionBuntDB `yaml:"buntdb"` + LevelDB SectionLevelDB `yaml:"leveldb"` } // SectionRedis is sub seciont of config. @@ -89,6 +90,11 @@ type SectionBuntDB struct { Path string `yaml:"path"` } +// SectionLevelDB is sub seciont of config. +type SectionLevelDB struct { + Path string `yaml:"path"` +} + // SectionPID is sub seciont of config. type SectionPID struct { Enabled bool `yaml:"enabled"` @@ -148,6 +154,7 @@ func BuildDefaultPushConf() ConfYaml { conf.Stat.BoltDB.Bucket = "gorush" conf.Stat.BuntDB.Path = "gorush.db" + conf.Stat.LevelDB.Path = "gorush.db" return conf } diff --git a/config/config.yml b/config/config.yml index 711b253..1d31289 100644 --- a/config/config.yml +++ b/config/config.yml @@ -49,3 +49,5 @@ stat: bucket: "gorush" buntdb: path: "gorush.db" + leveldb: + path: "gorush.db" diff --git a/config/config_test.go b/config/config_test.go index c22e674..7d6a9fd 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -102,6 +102,7 @@ func (suite *ConfigTestSuite) TestValidateConfDefault() { assert.Equal(suite.T(), "gorush", suite.ConfGorushDefault.Stat.BoltDB.Bucket) assert.Equal(suite.T(), "gorush.db", suite.ConfGorushDefault.Stat.BuntDB.Path) + assert.Equal(suite.T(), "gorush.db", suite.ConfGorushDefault.Stat.LevelDB.Path) } func (suite *ConfigTestSuite) TestValidateConf() { @@ -154,6 +155,7 @@ func (suite *ConfigTestSuite) TestValidateConf() { assert.Equal(suite.T(), "gorush", suite.ConfGorush.Stat.BoltDB.Bucket) assert.Equal(suite.T(), "gorush.db", suite.ConfGorush.Stat.BuntDB.Path) + assert.Equal(suite.T(), "gorush.db", suite.ConfGorush.Stat.LevelDB.Path) } func TestConfigTestSuite(t *testing.T) { diff --git a/glide.lock b/glide.lock index 31750c8..554ebfc 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: a723ec6556a185c4a20185378b0e042fd41453232da81489e06307b0ac8feba7 -updated: 2016-08-02T15:01:02.331147237+08:00 +hash: 6aef366747559fbcb1075ebe6f923f2e5197544a0b02ce039d5120c7241e8df2 +updated: 2016-09-19T15:54:05.13589289+08:00 imports: - name: github.com/asdine/storm version: 00b2f2df7ab7af9db746b826649395628cb5374e @@ -22,6 +22,8 @@ imports: version: 2402d76f3d41f928c7902a765dfc872356dd3aad subpackages: - proto +- name: github.com/golang/snappy + version: d9eb7a3d35ec988b8585d4a0068e462c27d28380 - name: github.com/google/go-gcm version: 190e93b4cedb43562b5bd558eb1a1bbd38695bcd - name: github.com/jpillora/backoff @@ -45,6 +47,21 @@ imports: - assert - suite - require +- name: github.com/syndtr/goleveldb + version: 6ae1797c0b42b9323fc27ff7dcf568df88f2f33d + subpackages: + - leveldb + - leveldb/cache + - leveldb/comparer + - leveldb/errors + - leveldb/filter + - leveldb/iterator + - leveldb/journal + - leveldb/memdb + - leveldb/opt + - leveldb/storage + - leveldb/table + - leveldb/util - name: github.com/thoas/stats version: 69e3c072eec2df2df41afe6214f62eb940e4cd80 - name: github.com/tidwall/btree @@ -103,9 +120,10 @@ imports: version: b5e368500d0a508ef8f16e9c2d4025a8a46bcc29 subpackages: - internal - - internal/consistenthash - internal/hashtag - internal/pool +- name: gopkg.in/redis.v3/internal/consistenthash + version: b5e368500d0a508ef8f16e9c2d4025a8a46bcc29 - name: gopkg.in/yaml.v2 version: a83829b6f1293c91addabc89d0571c246397bbf4 testImports: diff --git a/glide.yaml b/glide.yaml index 48453dc..3179b19 100644 --- a/glide.yaml +++ b/glide.yaml @@ -19,3 +19,4 @@ import: - package: github.com/buger/jsonparser - package: github.com/thoas/stats - package: github.com/tidwall/buntdb +- package: github.com/syndtr/goleveldb diff --git a/gorush/status.go b/gorush/status.go index d6c0740..a0dda3f 100644 --- a/gorush/status.go +++ b/gorush/status.go @@ -2,6 +2,8 @@ package gorush import ( "github.com/appleboy/gorush/storage/boltdb" + "github.com/appleboy/gorush/storage/buntdb" + "github.com/appleboy/gorush/storage/leveldb" "github.com/appleboy/gorush/storage/memory" "github.com/appleboy/gorush/storage/redis" "github.com/gin-gonic/gin" @@ -40,20 +42,24 @@ func InitAppStatus() error { StatStorage = memory.New() case "redis": StatStorage = redis.New(PushConf) - err := StatStorage.Init() - - if err != nil { - LogError.Error("redis error: " + err.Error()) - - return err - } - case "boltdb": StatStorage = boltdb.New(PushConf) + case "buntdb": + StatStorage = buntdb.New(PushConf) + case "leveldb": + StatStorage = leveldb.New(PushConf) default: StatStorage = memory.New() } + err := StatStorage.Init() + + if err != nil { + LogError.Error("storage error: " + err.Error()) + + return err + } + return nil } diff --git a/storage/leveldb/leveldb.go b/storage/leveldb/leveldb.go new file mode 100644 index 0000000..7064c95 --- /dev/null +++ b/storage/leveldb/leveldb.go @@ -0,0 +1,134 @@ +package leveldb + +import ( + "fmt" + "github.com/appleboy/gorush/config" + "github.com/syndtr/goleveldb/leveldb" + "strconv" +) + +// Stat variable for redis +const ( + TotalCountKey = "gorush-total-count" + IosSuccessKey = "gorush-ios-success-count" + IosErrorKey = "gorush-ios-error-count" + AndroidSuccessKey = "gorush-android-success-count" + AndroidErrorKey = "gorush-android-error-count" +) + +var dbPath string + +func setLevelDB(key string, count int64) { + db, _ := leveldb.OpenFile(dbPath, nil) + value := fmt.Sprintf("%d", count) + + _ = db.Put([]byte(key), []byte(value), nil) + + defer db.Close() +} + +func getLevelDB(key string, count *int64) { + db, _ := leveldb.OpenFile(dbPath, nil) + + data, _ := db.Get([]byte(key), nil) + *count, _ = strconv.ParseInt(string(data), 10, 64) + + defer db.Close() +} + +// New func implements the storage interface for gorush (https://github.com/appleboy/gorush) +func New(config config.ConfYaml) *Storage { + return &Storage{ + config: config, + } +} + +// Storage is interface structure +type Storage struct { + config config.ConfYaml +} + +// Init client storage. +func (s *Storage) Init() error { + dbPath = s.config.Stat.LevelDB.Path + return nil +} + +// Reset Client storage. +func (s *Storage) Reset() { + setLevelDB(TotalCountKey, 0) + setLevelDB(IosSuccessKey, 0) + setLevelDB(IosErrorKey, 0) + setLevelDB(AndroidSuccessKey, 0) + setLevelDB(AndroidErrorKey, 0) +} + +// AddTotalCount record push notification count. +func (s *Storage) AddTotalCount(count int64) { + total := s.GetTotalCount() + count + setLevelDB(TotalCountKey, total) +} + +// AddIosSuccess record counts of success iOS push notification. +func (s *Storage) AddIosSuccess(count int64) { + total := s.GetIosSuccess() + count + setLevelDB(IosSuccessKey, total) +} + +// AddIosError record counts of error iOS push notification. +func (s *Storage) AddIosError(count int64) { + total := s.GetIosError() + count + setLevelDB(IosErrorKey, total) +} + +// AddAndroidSuccess record counts of success Android push notification. +func (s *Storage) AddAndroidSuccess(count int64) { + total := s.GetAndroidSuccess() + count + setLevelDB(AndroidSuccessKey, total) +} + +// AddAndroidError record counts of error Android push notification. +func (s *Storage) AddAndroidError(count int64) { + total := s.GetAndroidError() + count + setLevelDB(AndroidErrorKey, total) +} + +// GetTotalCount show counts of all notification. +func (s *Storage) GetTotalCount() int64 { + var count int64 + getLevelDB(TotalCountKey, &count) + + return count +} + +// GetIosSuccess show success counts of iOS notification. +func (s *Storage) GetIosSuccess() int64 { + var count int64 + getLevelDB(IosSuccessKey, &count) + + return count +} + +// GetIosError show error counts of iOS notification. +func (s *Storage) GetIosError() int64 { + var count int64 + getLevelDB(IosErrorKey, &count) + + return count +} + +// GetAndroidSuccess show success counts of Android notification. +func (s *Storage) GetAndroidSuccess() int64 { + var count int64 + getLevelDB(AndroidSuccessKey, &count) + + return count +} + +// GetAndroidError show error counts of Android notification. +func (s *Storage) GetAndroidError() int64 { + var count int64 + getLevelDB(AndroidErrorKey, &count) + + return count +} diff --git a/storage/leveldb/leveldb_test.go b/storage/leveldb/leveldb_test.go new file mode 100644 index 0000000..82c9feb --- /dev/null +++ b/storage/leveldb/leveldb_test.go @@ -0,0 +1,49 @@ +package leveldb + +import ( + c "github.com/appleboy/gorush/config" + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +func TestLevelDBEngine(t *testing.T) { + var val int64 + + config := c.BuildDefaultPushConf() + + if _, err := os.Stat(config.Stat.LevelDB.Path); os.IsNotExist(err) { + os.RemoveAll(config.Stat.LevelDB.Path) + } + + levelDB := New(config) + levelDB.Init() + levelDB.Reset() + + levelDB.AddTotalCount(10) + val = levelDB.GetTotalCount() + assert.Equal(t, int64(10), val) + levelDB.AddTotalCount(10) + val = levelDB.GetTotalCount() + assert.Equal(t, int64(20), val) + + levelDB.AddIosSuccess(20) + val = levelDB.GetIosSuccess() + assert.Equal(t, int64(20), val) + + levelDB.AddIosError(30) + val = levelDB.GetIosError() + assert.Equal(t, int64(30), val) + + levelDB.AddAndroidSuccess(40) + val = levelDB.GetAndroidSuccess() + assert.Equal(t, int64(40), val) + + levelDB.AddAndroidError(50) + val = levelDB.GetAndroidError() + assert.Equal(t, int64(50), val) + + levelDB.Reset() + val = levelDB.GetAndroidError() + assert.Equal(t, int64(0), val) +}