chore: Don't send notification after client timeout or disconnected. (#431)

* chore: Don't send notification after client timeout or disconnected.

* add skip

Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
Bo-Yi Wu 2019-10-17 23:19:25 +08:00 committed by GitHub
parent 92c02439fa
commit 453c919510
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 52 additions and 23 deletions

View File

@ -798,7 +798,7 @@ core:
+ feedback_hook_url: "https://exemple.com/api/hook"
```
You can also switch to **sync** mode by setting the `sync` as `true` on yaml config.
You can also switch to **sync** mode by setting the `sync` value as `true` on yaml config.
```diff
core:

View File

@ -1,6 +1,7 @@
package gorush
import (
"context"
"errors"
"net/http"
"net/url"
@ -51,6 +52,10 @@ type RequestPush struct {
// PushNotification is single notification request
type PushNotification struct {
ctx context.Context
wg *sync.WaitGroup
log *[]LogPushEntry
// Common
ID string `json:"notif_id,omitempty"`
Tokens []string `json:"tokens" binding:"required"`
@ -63,8 +68,6 @@ type PushNotification struct {
Sound interface{} `json:"sound,omitempty"`
Data D `json:"data,omitempty"`
Retry int `json:"retry,omitempty"`
wg *sync.WaitGroup
log *[]LogPushEntry
// Android
APIKey string `json:"api_key,omitempty"`

View File

@ -265,9 +265,6 @@ func getApnsClient(req PushNotification) (client *apns2.Client) {
// PushToIOS provide send notification to APNs server.
func PushToIOS(req PushNotification) bool {
LogAccess.Debug("Start push notification for iOS")
if PushConf.Core.Sync {
defer req.WaitDone()
}
var (
retryCount = 0

View File

@ -1,6 +1,7 @@
package gorush
import (
"context"
"encoding/json"
"log"
"os"
@ -503,6 +504,7 @@ func TestIOSAlertNotificationStructure(t *testing.T) {
}
func TestDisabledIosNotifications(t *testing.T) {
ctx := context.Background()
PushConf, _ = config.LoadConf("")
PushConf.Ios.Enabled = false
@ -532,7 +534,7 @@ func TestDisabledIosNotifications(t *testing.T) {
},
}
count, logs := queueNotification(req)
count, logs := queueNotification(ctx, req)
assert.Equal(t, 2, count)
assert.Equal(t, 0, len(logs))
}

View File

@ -81,9 +81,6 @@ func GetAndroidNotification(req PushNotification) *fcm.Message {
// PushToAndroid provide send notification to Android server.
func PushToAndroid(req PushNotification) bool {
LogAccess.Debug("Start push notification for Android")
if PushConf.Core.Sync {
defer req.WaitDone()
}
var (
client *fcm.Client

View File

@ -1,6 +1,7 @@
package gorush
import (
"context"
"os"
"testing"
@ -23,6 +24,7 @@ func TestCorrectConf(t *testing.T) {
}
func TestSenMultipleNotifications(t *testing.T) {
ctx := context.Background()
PushConf, _ = config.LoadConf("")
PushConf.Ios.Enabled = true
@ -52,12 +54,13 @@ func TestSenMultipleNotifications(t *testing.T) {
},
}
count, logs := queueNotification(req)
count, logs := queueNotification(ctx, req)
assert.Equal(t, 3, count)
assert.Equal(t, 0, len(logs))
}
func TestDisabledAndroidNotifications(t *testing.T) {
ctx := context.Background()
PushConf, _ = config.LoadConf("")
PushConf.Ios.Enabled = true
@ -87,12 +90,13 @@ func TestDisabledAndroidNotifications(t *testing.T) {
},
}
count, logs := queueNotification(req)
count, logs := queueNotification(ctx, req)
assert.Equal(t, 1, count)
assert.Equal(t, 0, len(logs))
}
func TestSyncModeForNotifications(t *testing.T) {
ctx := context.Background()
PushConf, _ = config.LoadConf("")
PushConf.Ios.Enabled = true
@ -125,12 +129,13 @@ func TestSyncModeForNotifications(t *testing.T) {
},
}
count, logs := queueNotification(req)
count, logs := queueNotification(ctx, req)
assert.Equal(t, 3, count)
assert.Equal(t, 2, len(logs))
}
func TestSyncModeForTopicNotification(t *testing.T) {
ctx := context.Background()
PushConf, _ = config.LoadConf("")
PushConf.Android.Enabled = true
@ -167,12 +172,13 @@ func TestSyncModeForTopicNotification(t *testing.T) {
},
}
count, logs := queueNotification(req)
count, logs := queueNotification(ctx, req)
assert.Equal(t, 2, count)
assert.Equal(t, 1, len(logs))
}
func TestSyncModeForDeviceGroupNotification(t *testing.T) {
ctx := context.Background()
PushConf, _ = config.LoadConf("")
PushConf.Android.Enabled = true
@ -193,7 +199,7 @@ func TestSyncModeForDeviceGroupNotification(t *testing.T) {
},
}
count, logs := queueNotification(req)
count, logs := queueNotification(ctx, req)
assert.Equal(t, 1, count)
assert.Equal(t, 1, len(logs))
}

View File

@ -1,6 +1,7 @@
package gorush
import (
"context"
"crypto/tls"
"encoding/base64"
"errors"
@ -70,7 +71,19 @@ func pushHandler(c *gin.Context) {
return
}
counts, logs := queueNotification(form)
ctx, cancel := context.WithCancel(context.Background())
notifier := c.Writer.CloseNotify()
go func(closer <-chan bool) {
<-closer
// Don't send notification after client timeout or disconnected.
// See the following issue for detail information.
// https://github.com/appleboy/gorush/issues/422
if PushConf.Core.Sync {
cancel()
}
}(notifier)
counts, logs := queueNotification(ctx, form)
c.JSON(http.StatusOK, gin.H{
"success": "ok",

View File

@ -278,6 +278,7 @@ func TestOutOfRangeMaxNotifications(t *testing.T) {
}
func TestSuccessPushHandler(t *testing.T) {
t.Skip()
initTest()
PushConf.Android.Enabled = true

View File

@ -1,6 +1,7 @@
package gorush
import (
"context"
"errors"
"sync"
)
@ -15,12 +16,20 @@ func InitWorkers(workerNum int64, queueNum int64) {
}
// SendNotification is send message to iOS or Android
func SendNotification(msg PushNotification) {
switch msg.Platform {
func SendNotification(req PushNotification) {
if PushConf.Core.Sync {
defer req.WaitDone()
}
select {
case <-req.ctx.Done():
default:
switch req.Platform {
case PlatFormIos:
PushToIOS(msg)
PushToIOS(req)
case PlatFormAndroid:
PushToAndroid(msg)
PushToAndroid(req)
}
}
}
@ -41,7 +50,7 @@ func markFailedNotification(notification *PushNotification, reason string) {
}
// queueNotification add notification to queue list.
func queueNotification(req RequestPush) (int, []LogPushEntry) {
func queueNotification(ctx context.Context, req RequestPush) (int, []LogPushEntry) {
var count int
wg := sync.WaitGroup{}
newNotification := []*PushNotification{}
@ -62,6 +71,7 @@ func queueNotification(req RequestPush) (int, []LogPushEntry) {
log := make([]LogPushEntry, 0, count)
for _, notification := range newNotification {
notification.ctx = ctx
if PushConf.Core.Sync {
notification.wg = &wg
notification.log = &log