feat: support sync mode for http response. (#208)

* feat: support sync mode for http response.

* fix: update readme.

* fix: check wg exist.

* fix: testing sync mode.
This commit is contained in:
Bo-Yi Wu 2017-04-06 15:00:49 +08:00 committed by GitHub
parent fcdd369cec
commit b6997ea792
7 changed files with 62 additions and 6 deletions

View File

@ -63,6 +63,7 @@ core:
worker_num: 0 # default worker number is runtime.NumCPU()
queue_num: 0 # default queue number is 8192
max_notification: 100
sync: false # set true if you get http response after finish send notification.
mode: "release"
ssl: false
cert_path: "cert.pem"

View File

@ -24,6 +24,7 @@ type SectionCore struct {
WorkerNum int64 `yaml:"worker_num"`
QueueNum int64 `yaml:"queue_num"`
Mode string `yaml:"mode"`
Sync bool `yaml:"sync"`
SSL bool `yaml:"ssl"`
CertPath string `yaml:"cert_path"`
KeyPath string `yaml:"key_path"`
@ -123,6 +124,7 @@ func BuildDefaultPushConf() ConfYaml {
conf.Core.WorkerNum = int64(runtime.NumCPU())
conf.Core.QueueNum = int64(8192)
conf.Core.Mode = "release"
conf.Core.Sync = false
conf.Core.SSL = false
conf.Core.CertPath = "cert.pem"
conf.Core.KeyPath = "key.pem"

View File

@ -3,6 +3,7 @@ core:
worker_num: 0 # default worker number is runtime.NumCPU()
queue_num: 0 # default queue number is 8192
max_notification: 100
sync: false # set true if you get http response after finish send notification.
mode: "release"
ssl: false
cert_path: "cert.pem"

View File

@ -59,6 +59,7 @@ func (suite *ConfigTestSuite) TestValidateConfDefault() {
assert.Equal(suite.T(), int64(runtime.NumCPU()), suite.ConfGorushDefault.Core.WorkerNum)
assert.Equal(suite.T(), int64(8192), suite.ConfGorushDefault.Core.QueueNum)
assert.Equal(suite.T(), "release", suite.ConfGorushDefault.Core.Mode)
assert.Equal(suite.T(), false, suite.ConfGorushDefault.Core.Sync)
assert.Equal(suite.T(), false, suite.ConfGorushDefault.Core.SSL)
assert.Equal(suite.T(), "cert.pem", suite.ConfGorushDefault.Core.CertPath)
assert.Equal(suite.T(), "key.pem", suite.ConfGorushDefault.Core.KeyPath)
@ -118,6 +119,7 @@ func (suite *ConfigTestSuite) TestValidateConf() {
assert.Equal(suite.T(), int64(runtime.NumCPU()), suite.ConfGorush.Core.WorkerNum)
assert.Equal(suite.T(), int64(8192), suite.ConfGorush.Core.QueueNum)
assert.Equal(suite.T(), "release", suite.ConfGorush.Core.Mode)
assert.Equal(suite.T(), false, suite.ConfGorush.Core.Sync)
assert.Equal(suite.T(), false, suite.ConfGorush.Core.SSL)
assert.Equal(suite.T(), "cert.pem", suite.ConfGorush.Core.CertPath)
assert.Equal(suite.T(), "key.pem", suite.ConfGorush.Core.KeyPath)

View File

@ -7,6 +7,7 @@ import (
"net/url"
"os"
"path/filepath"
"sync"
"time"
"github.com/google/go-gcm"
@ -63,6 +64,7 @@ type PushNotification struct {
Sound string `json:"sound,omitempty"`
Data D `json:"data,omitempty"`
Retry int `json:"retry,omitempty"`
wg *sync.WaitGroup
// Android
APIKey string `json:"api_key,omitempty"`
@ -85,6 +87,13 @@ type PushNotification struct {
MutableContent bool `json:"mutable-content,omitempty"`
}
// Done decrements the WaitGroup counter.
func (p *PushNotification) Done() {
if p.wg != nil {
p.wg.Done()
}
}
// CheckMessage for check request message
func CheckMessage(req PushNotification) error {
var msg string
@ -214,6 +223,7 @@ func startWorker() {
// queueNotification add notification to queue list.
func queueNotification(req RequestPush) int {
var count int
wg := sync.WaitGroup{}
for _, notification := range req.Notifications {
switch notification.Platform {
case PlatFormIos:
@ -225,11 +235,16 @@ func queueNotification(req RequestPush) int {
continue
}
}
wg.Add(1)
notification.wg = &wg
QueueNotification <- notification
count += len(notification.Tokens)
}
if PushConf.Core.Sync {
wg.Wait()
}
StatStorage.AddTotalCount(int64(count))
return count
@ -351,7 +366,7 @@ func GetIOSNotification(req PushNotification) *apns.Notification {
// PushToIOS provide send notification to APNs server.
func PushToIOS(req PushNotification) bool {
LogAccess.Debug("Start push notification for iOS")
defer req.Done()
var retryCount = 0
var maxRetry = PushConf.Ios.MaxRetry
@ -456,7 +471,7 @@ func GetAndroidNotification(req PushNotification) gcm.HttpMessage {
// PushToAndroid provide send notification to Android server.
func PushToAndroid(req PushNotification) bool {
LogAccess.Debug("Start push notification for Android")
defer req.Done()
var APIKey string
var retryCount = 0
var maxRetry = PushConf.Android.MaxRetry
@ -486,7 +501,6 @@ Retry:
if err != nil {
// GCM server error
LogError.Error("GCM server error: " + err.Error())
return false
}

View File

@ -604,6 +604,42 @@ func TestDisabledAndroidNotifications(t *testing.T) {
assert.Equal(t, 1, count)
}
func TestSyncModeForNotifications(t *testing.T) {
PushConf = config.BuildDefaultPushConf()
PushConf.Ios.Enabled = true
PushConf.Ios.KeyPath = "../certificate/certificate-valid.pem"
InitAPNSClient()
PushConf.Android.Enabled = true
PushConf.Android.APIKey = os.Getenv("ANDROID_API_KEY")
// enable sync mode
PushConf.Core.Sync = true
androidToken := os.Getenv("ANDROID_TEST_TOKEN")
req := RequestPush{
Notifications: []PushNotification{
//ios
{
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
Platform: PlatFormIos,
Message: "Welcome",
},
// android
{
Tokens: []string{androidToken, "bbbbb"},
Platform: PlatFormAndroid,
Message: "Welcome",
},
},
}
count := queueNotification(req)
assert.Equal(t, 3, count)
}
func TestDisabledIosNotifications(t *testing.T) {
PushConf = config.BuildDefaultPushConf()

View File

@ -56,11 +56,11 @@ func pushHandler(c *gin.Context) {
return
}
// queue notification.
go queueNotification(form)
counts := queueNotification(form)
c.JSON(http.StatusOK, gin.H{
"success": "ok",
"counts": counts,
})
}