From f5857f54b03b8188aded1e1694957dcd9d22381f Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Sat, 23 Apr 2016 15:13:57 +0800 Subject: [PATCH 1/4] Feature #58 support BoltDB engine Signed-off-by: Bo-Yi Wu --- .gitignore | 1 + README.md | 5 +++- config/config.yml | 3 +++ gorush/config.go | 10 +++++++ gorush/status.go | 52 +++++++++++++++++++++++++++++++---- gorush/status_test.go | 63 +++++++++++++++++++++++++++++-------------- 6 files changed, 108 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index 56bf979..91a8b23 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ coverage.out gorush/log/*.log build.tar.gz gorush.tar.gz +gorush.db diff --git a/README.md b/README.md index af72368..340f579 100644 --- a/README.md +++ b/README.md @@ -60,11 +60,14 @@ log: error_level: "error" stat: - engine: "memory" # support memory or redis + engine: "memory" # support memory, redis or boltdb redis: addr: "localhost:6379" password: "" db: 0 + boltdb: + path: "gorush.db" + bucket: "gorush" ``` ## Basic Usage diff --git a/config/config.yml b/config/config.yml index dd96f17..5fb8558 100644 --- a/config/config.yml +++ b/config/config.yml @@ -37,3 +37,6 @@ stat: addr: "localhost:6379" password: "" db: 0 + boltdb: + path: "gorush.db" + bucket: "gorush" diff --git a/gorush/config.go b/gorush/config.go index 29a8899..dc6f85a 100644 --- a/gorush/config.go +++ b/gorush/config.go @@ -63,6 +63,7 @@ type SectionLog struct { type SectionStat struct { Engine string `yaml:"service"` Redis SectionRedis `yaml:"redis"` + BoltDB SectionBoltDB `yaml:"boltdb"` } // SectionRedis is sub seciont of config. @@ -72,6 +73,12 @@ type SectionRedis struct { DB int64 `yaml:"db"` } +// SectionBoltDB is sub seciont of config. +type SectionBoltDB struct { + Path string `yaml:"path"` + Bucket string `yaml:"bucket"` +} + // BuildDefaultPushConf is default config setting. func BuildDefaultPushConf() ConfYaml { var conf ConfYaml @@ -114,6 +121,9 @@ func BuildDefaultPushConf() ConfYaml { conf.Stat.Redis.Password = "" conf.Stat.Redis.DB = 0 + conf.Stat.BoltDB.Path = "gorush.db" + conf.Stat.BoltDB.Bucket = "gorush" + return conf } diff --git a/gorush/status.go b/gorush/status.go index d75122f..27fd686 100644 --- a/gorush/status.go +++ b/gorush/status.go @@ -6,6 +6,7 @@ import ( "net/http" "strconv" "sync/atomic" + "github.com/asdine/storm" ) // StatusApp is app status structure @@ -69,6 +70,14 @@ func initRedis() error { return nil } +func initBoltDB() { + RushStatus.TotalCount = getTotalCount() + RushStatus.Ios.PushSuccess = getIosSuccess() + RushStatus.Ios.PushError = getIosError() + RushStatus.Android.PushSuccess = getAndroidSuccess() + RushStatus.Android.PushError = getAndroidError() +} + // InitAppStatus for initialize app status func InitAppStatus() { switch PushConf.Stat.Engine { @@ -76,18 +85,34 @@ func InitAppStatus() { initApp() case "redis": initRedis() + case "boltdb": + initBoltDB() default: initApp() } } +func boltdbSet(key string, count int64) { + db, _ := storm.Open(PushConf.Stat.BoltDB.Path) + db.Set(PushConf.Stat.BoltDB.Bucket, key, count) + defer db.Close() +} + +func boltdbGet(key string, count *int64) { + db, _ := storm.Open(PushConf.Stat.BoltDB.Path) + db.Get(PushConf.Stat.BoltDB.Bucket, key, count) + defer db.Close() +} + func addTotalCount(count int64) { switch PushConf.Stat.Engine { case "memory": atomic.AddInt64(&RushStatus.TotalCount, count) case "redis": RedisClient.Set(gorushTotalCount, strconv.Itoa(int(count)), 0) + case "boltdb": + boltdbSet(gorushTotalCount, count) default: atomic.AddInt64(&RushStatus.TotalCount, count) } @@ -99,6 +124,8 @@ func addIosSuccess(count int64) { atomic.AddInt64(&RushStatus.Ios.PushSuccess, count) case "redis": RedisClient.Set(gorushIosSuccess, strconv.Itoa(int(count)), 0) + case "boltdb": + boltdbSet(gorushIosSuccess, count) default: atomic.AddInt64(&RushStatus.Ios.PushSuccess, count) } @@ -110,6 +137,8 @@ func addIosError(count int64) { atomic.AddInt64(&RushStatus.Ios.PushError, count) case "redis": RedisClient.Set(gorushIosError, strconv.Itoa(int(count)), 0) + case "boltdb": + boltdbSet(gorushIosError, count) default: atomic.AddInt64(&RushStatus.Ios.PushError, count) } @@ -120,8 +149,9 @@ func addAndroidSuccess(count int64) { case "memory": atomic.AddInt64(&RushStatus.Android.PushSuccess, count) case "redis": - RedisClient.Set(gorushAndroidSuccess, strconv.Itoa(int(count)), 0) + case "boltdb": + boltdbSet(gorushAndroidSuccess, count) default: atomic.AddInt64(&RushStatus.Android.PushSuccess, count) } @@ -133,6 +163,8 @@ func addAndroidError(count int64) { atomic.AddInt64(&RushStatus.Android.PushError, count) case "redis": RedisClient.Set(gorushAndroidError, strconv.Itoa(int(count)), 0) + case "boltdb": + boltdbSet(gorushAndroidError, count) default: atomic.AddInt64(&RushStatus.Android.PushError, count) } @@ -144,7 +176,9 @@ func getTotalCount() int64 { case "memory": count = atomic.LoadInt64(&RushStatus.TotalCount) case "redis": - count = getRedisInt64Result(gorushAndroidError) + count = getRedisInt64Result(gorushTotalCount) + case "boltdb": + boltdbGet(gorushTotalCount, &count) default: count = atomic.LoadInt64(&RushStatus.TotalCount) } @@ -158,7 +192,9 @@ func getIosSuccess() int64 { case "memory": count = atomic.LoadInt64(&RushStatus.Ios.PushSuccess) case "redis": - count = getRedisInt64Result(gorushAndroidError) + count = getRedisInt64Result(gorushIosSuccess) + case "boltdb": + boltdbGet(gorushIosSuccess, &count) default: count = atomic.LoadInt64(&RushStatus.Ios.PushSuccess) } @@ -172,7 +208,9 @@ func getIosError() int64 { case "memory": count = atomic.LoadInt64(&RushStatus.Ios.PushError) case "redis": - count = getRedisInt64Result(gorushAndroidError) + count = getRedisInt64Result(gorushIosError) + case "boltdb": + boltdbGet(gorushIosError, &count) default: count = atomic.LoadInt64(&RushStatus.Ios.PushError) } @@ -186,7 +224,9 @@ func getAndroidSuccess() int64 { case "memory": count = atomic.LoadInt64(&RushStatus.Android.PushSuccess) case "redis": - count = getRedisInt64Result(gorushAndroidError) + count = getRedisInt64Result(gorushAndroidSuccess) + case "boltdb": + boltdbGet(gorushAndroidSuccess, &count) default: count = atomic.LoadInt64(&RushStatus.Android.PushSuccess) } @@ -201,6 +241,8 @@ func getAndroidError() int64 { count = atomic.LoadInt64(&RushStatus.Android.PushError) case "redis": count = getRedisInt64Result(gorushAndroidError) + case "boltdb": + boltdbGet(gorushAndroidError, &count) default: count = atomic.LoadInt64(&RushStatus.Android.PushError) } diff --git a/gorush/status_test.go b/gorush/status_test.go index c80c1f4..044d4a1 100644 --- a/gorush/status_test.go +++ b/gorush/status_test.go @@ -73,22 +73,22 @@ func TestStatForRedisEngine(t *testing.T) { PushConf.Stat.Redis.Addr = "localhost:6379" InitAppStatus() - addTotalCount(1000) - addIosSuccess(1000) - addIosError(1000) - addAndroidSuccess(1000) - addAndroidError(1000) + addTotalCount(10) + addIosSuccess(20) + addIosError(30) + addAndroidSuccess(40) + addAndroidError(50) val = getTotalCount() - assert.Equal(t, int64(1000), val) + assert.Equal(t, int64(10), val) val = getIosSuccess() - assert.Equal(t, int64(1000), val) + assert.Equal(t, int64(20), val) val = getIosError() - assert.Equal(t, int64(1000), val) + assert.Equal(t, int64(30), val) val = getAndroidSuccess() - assert.Equal(t, int64(1000), val) + assert.Equal(t, int64(40), val) val = getAndroidError() - assert.Equal(t, int64(1000), val) + assert.Equal(t, int64(50), val) } func TestDefaultEngine(t *testing.T) { @@ -96,20 +96,43 @@ func TestDefaultEngine(t *testing.T) { PushConf.Stat.Engine = "test" InitAppStatus() - addTotalCount(1000) - addIosSuccess(1000) - addIosError(1000) - addAndroidSuccess(1000) - addAndroidError(1000) + addTotalCount(1) + addIosSuccess(2) + addIosError(3) + addAndroidSuccess(4) + addAndroidError(5) val = getTotalCount() - assert.Equal(t, int64(1000), val) + assert.Equal(t, int64(1), val) val = getIosSuccess() - assert.Equal(t, int64(1000), val) + assert.Equal(t, int64(2), val) val = getIosError() - assert.Equal(t, int64(1000), val) + assert.Equal(t, int64(3), val) val = getAndroidSuccess() - assert.Equal(t, int64(1000), val) + assert.Equal(t, int64(4), val) val = getAndroidError() - assert.Equal(t, int64(1000), val) + assert.Equal(t, int64(5), val) +} + +func TestStatForBoltDBEngine(t *testing.T) { + var val int64 + PushConf.Stat.Engine = "boltdb" + InitAppStatus() + + addTotalCount(100) + addIosSuccess(200) + addIosError(300) + addAndroidSuccess(400) + addAndroidError(500) + + val = getTotalCount() + assert.Equal(t, int64(100), val) + val = getIosSuccess() + assert.Equal(t, int64(200), val) + val = getIosError() + assert.Equal(t, int64(300), val) + val = getAndroidSuccess() + assert.Equal(t, int64(400), val) + val = getAndroidError() + assert.Equal(t, int64(500), val) } From 8e79329131172e5c3c38b60de7482f1197078a2f Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Sat, 23 Apr 2016 15:20:30 +0800 Subject: [PATCH 2/4] update redis func Signed-off-by: Bo-Yi Wu --- gorush/status.go | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/gorush/status.go b/gorush/status.go index 27fd686..27dd7d9 100644 --- a/gorush/status.go +++ b/gorush/status.go @@ -30,13 +30,6 @@ type IosStatus struct { PushError int64 `json:"push_error"` } -func getRedisInt64Result(key string) int64 { - val, _ := RedisClient.Get(key).Result() - count, _ := strconv.ParseInt(val, 10, 64) - - return count -} - func initApp() { RushStatus.TotalCount = 0 RushStatus.Ios.PushSuccess = 0 @@ -93,6 +86,11 @@ func InitAppStatus() { } +func getRedisInt64Result(key string, count *int64) { + val, _ := RedisClient.Get(key).Result() + *count, _ = strconv.ParseInt(val, 10, 64) +} + func boltdbSet(key string, count int64) { db, _ := storm.Open(PushConf.Stat.BoltDB.Path) db.Set(PushConf.Stat.BoltDB.Bucket, key, count) @@ -176,7 +174,7 @@ func getTotalCount() int64 { case "memory": count = atomic.LoadInt64(&RushStatus.TotalCount) case "redis": - count = getRedisInt64Result(gorushTotalCount) + getRedisInt64Result(gorushTotalCount, &count) case "boltdb": boltdbGet(gorushTotalCount, &count) default: @@ -192,7 +190,7 @@ func getIosSuccess() int64 { case "memory": count = atomic.LoadInt64(&RushStatus.Ios.PushSuccess) case "redis": - count = getRedisInt64Result(gorushIosSuccess) + getRedisInt64Result(gorushIosSuccess, &count) case "boltdb": boltdbGet(gorushIosSuccess, &count) default: @@ -208,7 +206,7 @@ func getIosError() int64 { case "memory": count = atomic.LoadInt64(&RushStatus.Ios.PushError) case "redis": - count = getRedisInt64Result(gorushIosError) + getRedisInt64Result(gorushIosError, &count) case "boltdb": boltdbGet(gorushIosError, &count) default: @@ -224,7 +222,7 @@ func getAndroidSuccess() int64 { case "memory": count = atomic.LoadInt64(&RushStatus.Android.PushSuccess) case "redis": - count = getRedisInt64Result(gorushAndroidSuccess) + getRedisInt64Result(gorushAndroidSuccess, &count) case "boltdb": boltdbGet(gorushAndroidSuccess, &count) default: @@ -240,7 +238,7 @@ func getAndroidError() int64 { case "memory": count = atomic.LoadInt64(&RushStatus.Android.PushError) case "redis": - count = getRedisInt64Result(gorushAndroidError) + getRedisInt64Result(gorushAndroidError, &count) case "boltdb": boltdbGet(gorushAndroidError, &count) default: From 48c792ad430a5cea597ed7e92861aad517ea66fa Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Sat, 23 Apr 2016 15:20:42 +0800 Subject: [PATCH 3/4] fix gofmt. Signed-off-by: Bo-Yi Wu --- gorush/config.go | 6 +++--- gorush/const.go | 8 ++++---- gorush/status.go | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gorush/config.go b/gorush/config.go index dc6f85a..7511ee7 100644 --- a/gorush/config.go +++ b/gorush/config.go @@ -61,8 +61,8 @@ type SectionLog struct { // SectionStat is sub seciont of config. type SectionStat struct { - Engine string `yaml:"service"` - Redis SectionRedis `yaml:"redis"` + Engine string `yaml:"service"` + Redis SectionRedis `yaml:"redis"` BoltDB SectionBoltDB `yaml:"boltdb"` } @@ -75,7 +75,7 @@ type SectionRedis struct { // SectionBoltDB is sub seciont of config. type SectionBoltDB struct { - Path string `yaml:"path"` + Path string `yaml:"path"` Bucket string `yaml:"bucket"` } diff --git a/gorush/const.go b/gorush/const.go index dc3fb6f..28f5ca1 100644 --- a/gorush/const.go +++ b/gorush/const.go @@ -21,9 +21,9 @@ const ( // Stat variable for redis const ( - gorushTotalCount = "gorush-total-count" - gorushIosSuccess = "gorush-ios-success-count" - gorushIosError = "gorush-ios-error-count" + gorushTotalCount = "gorush-total-count" + gorushIosSuccess = "gorush-ios-success-count" + gorushIosError = "gorush-ios-error-count" gorushAndroidSuccess = "gorush-android-success-count" - gorushAndroidError = "gorush-android-error-count" + gorushAndroidError = "gorush-android-error-count" ) diff --git a/gorush/status.go b/gorush/status.go index 27dd7d9..10fa817 100644 --- a/gorush/status.go +++ b/gorush/status.go @@ -1,12 +1,12 @@ package gorush import ( + "github.com/asdine/storm" "github.com/gin-gonic/gin" "gopkg.in/redis.v3" "net/http" "strconv" "sync/atomic" - "github.com/asdine/storm" ) // StatusApp is app status structure From 88183ffbba1148b2ae8778807e361f7610e1fa04 Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Sat, 23 Apr 2016 15:46:17 +0800 Subject: [PATCH 4/4] fix json name. Signed-off-by: Bo-Yi Wu --- README.md | 2 +- gorush/config.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 340f579..f1363f2 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ A push notification server using [Gin](https://github.com/gin-gonic/gin) framewo * Support notification queue and multiple workers. * Support `/api/stat/app` show notification success and failure counts. * Support `/api/config` show your yml config. -* Support store app stat to [redis](http://redis.io/) or memory. +* Support store app stat to memory, [redis](http://redis.io/) or [BoltDB](https://github.com/boltdb/bolt). See the [YAML config example](config/config.yml): diff --git a/gorush/config.go b/gorush/config.go index 7511ee7..4e8f60e 100644 --- a/gorush/config.go +++ b/gorush/config.go @@ -61,7 +61,7 @@ type SectionLog struct { // SectionStat is sub seciont of config. type SectionStat struct { - Engine string `yaml:"service"` + Engine string `yaml:"engine"` Redis SectionRedis `yaml:"redis"` BoltDB SectionBoltDB `yaml:"boltdb"` }