chore: fix race condition with push iOS notification (#533)
This commit is contained in:
parent
7c7e740fec
commit
a4cc8d7582
|
@ -360,7 +360,7 @@ func getApnsClient(req PushNotification) (client *apns2.Client) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PushToIOS provide send notification to APNs server.
|
// PushToIOS provide send notification to APNs server.
|
||||||
func PushToIOS(req PushNotification) bool {
|
func PushToIOS(req PushNotification) {
|
||||||
LogAccess.Debug("Start push notification for iOS")
|
LogAccess.Debug("Start push notification for iOS")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -374,7 +374,6 @@ func PushToIOS(req PushNotification) bool {
|
||||||
|
|
||||||
Retry:
|
Retry:
|
||||||
var (
|
var (
|
||||||
isError = false
|
|
||||||
newTokens []string
|
newTokens []string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -386,12 +385,11 @@ Retry:
|
||||||
// occupy push slot
|
// occupy push slot
|
||||||
MaxConcurrentIOSPushes <- struct{}{}
|
MaxConcurrentIOSPushes <- struct{}{}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(token string) {
|
go func(notification apns2.Notification, token string) {
|
||||||
notification.DeviceToken = token
|
notification.DeviceToken = token
|
||||||
|
|
||||||
// send ios notification
|
// send ios notification
|
||||||
res, err := client.Push(notification)
|
res, err := client.Push(¬ification)
|
||||||
|
|
||||||
if err != nil || (res != nil && res.StatusCode != http.StatusOK) {
|
if err != nil || (res != nil && res.StatusCode != http.StatusOK) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// error message:
|
// error message:
|
||||||
|
@ -418,27 +416,24 @@ Retry:
|
||||||
if res != nil && res.StatusCode >= http.StatusInternalServerError {
|
if res != nil && res.StatusCode >= http.StatusInternalServerError {
|
||||||
newTokens = append(newTokens, token)
|
newTokens = append(newTokens, token)
|
||||||
}
|
}
|
||||||
isError = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if res != nil && res.Sent() && !isError {
|
if res != nil && res.Sent() {
|
||||||
LogPush(SucceededPush, token, req, nil)
|
LogPush(SucceededPush, token, req, nil)
|
||||||
StatStorage.AddIosSuccess(1)
|
StatStorage.AddIosSuccess(1)
|
||||||
}
|
}
|
||||||
// free push slot
|
// free push slot
|
||||||
<-MaxConcurrentIOSPushes
|
<-MaxConcurrentIOSPushes
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}(token)
|
}(*notification, token)
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if isError && retryCount < maxRetry {
|
if len(newTokens) > 0 && retryCount < maxRetry {
|
||||||
retryCount++
|
retryCount++
|
||||||
|
|
||||||
// resend fail token
|
// resend fail token
|
||||||
req.Tokens = newTokens
|
req.Tokens = newTokens
|
||||||
goto Retry
|
goto Retry
|
||||||
}
|
}
|
||||||
|
|
||||||
return isError
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -706,14 +706,13 @@ func TestPushToIOS(t *testing.T) {
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
req := PushNotification{
|
req := PushNotification{
|
||||||
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"},
|
Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7", "11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef1"},
|
||||||
Platform: 1,
|
Platform: 1,
|
||||||
Message: "Welcome",
|
Message: "Welcome",
|
||||||
}
|
}
|
||||||
|
|
||||||
// send fail
|
// send fail
|
||||||
isError := PushToIOS(req)
|
PushToIOS(req)
|
||||||
assert.True(t, isError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApnsHostFromRequest(t *testing.T) {
|
func TestApnsHostFromRequest(t *testing.T) {
|
||||||
|
|
|
@ -101,7 +101,7 @@ func GetAndroidNotification(req PushNotification) *fcm.Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PushToAndroid provide send notification to Android server.
|
// PushToAndroid provide send notification to Android server.
|
||||||
func PushToAndroid(req PushNotification) bool {
|
func PushToAndroid(req PushNotification) {
|
||||||
LogAccess.Debug("Start push notification for Android")
|
LogAccess.Debug("Start push notification for Android")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -119,12 +119,10 @@ func PushToAndroid(req PushNotification) bool {
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError.Error("request error: " + err.Error())
|
LogError.Error("request error: " + err.Error())
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Retry:
|
Retry:
|
||||||
var isError = false
|
|
||||||
|
|
||||||
notification := GetAndroidNotification(req)
|
notification := GetAndroidNotification(req)
|
||||||
|
|
||||||
if req.APIKey != "" {
|
if req.APIKey != "" {
|
||||||
|
@ -136,14 +134,14 @@ Retry:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FCM server error
|
// FCM server error
|
||||||
LogError.Error("FCM server error: " + err.Error())
|
LogError.Error("FCM server error: " + err.Error())
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := client.Send(notification)
|
res, err := client.Send(notification)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Send Message error
|
// Send Message error
|
||||||
LogError.Error("FCM server send message error: " + err.Error())
|
LogError.Error("FCM server send message error: " + err.Error())
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !req.IsTopic() {
|
if !req.IsTopic() {
|
||||||
|
@ -169,7 +167,6 @@ Retry:
|
||||||
if !result.Unregistered() {
|
if !result.Unregistered() {
|
||||||
newTokens = append(newTokens, to)
|
newTokens = append(newTokens, to)
|
||||||
}
|
}
|
||||||
isError = true
|
|
||||||
|
|
||||||
LogPush(FailedPush, to, req, result.Error)
|
LogPush(FailedPush, to, req, result.Error)
|
||||||
if PushConf.Core.Sync {
|
if PushConf.Core.Sync {
|
||||||
|
@ -201,7 +198,6 @@ Retry:
|
||||||
if res.MessageID != 0 {
|
if res.MessageID != 0 {
|
||||||
LogPush(SucceededPush, to, req, nil)
|
LogPush(SucceededPush, to, req, nil)
|
||||||
} else {
|
} else {
|
||||||
isError = true
|
|
||||||
// failure
|
// failure
|
||||||
LogPush(FailedPush, to, req, res.Error)
|
LogPush(FailedPush, to, req, res.Error)
|
||||||
if PushConf.Core.Sync {
|
if PushConf.Core.Sync {
|
||||||
|
@ -212,7 +208,6 @@ Retry:
|
||||||
|
|
||||||
// Device Group HTTP Response
|
// Device Group HTTP Response
|
||||||
if len(res.FailedRegistrationIDs) > 0 {
|
if len(res.FailedRegistrationIDs) > 0 {
|
||||||
isError = true
|
|
||||||
newTokens = append(newTokens, res.FailedRegistrationIDs...)
|
newTokens = append(newTokens, res.FailedRegistrationIDs...)
|
||||||
|
|
||||||
LogPush(FailedPush, notification.To, req, errors.New("device group: partial success or all fails"))
|
LogPush(FailedPush, notification.To, req, errors.New("device group: partial success or all fails"))
|
||||||
|
@ -221,13 +216,11 @@ Retry:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isError && retryCount < maxRetry {
|
if len(newTokens) > 0 && retryCount < maxRetry {
|
||||||
retryCount++
|
retryCount++
|
||||||
|
|
||||||
// resend fail token
|
// resend fail token
|
||||||
req.Tokens = newTokens
|
req.Tokens = newTokens
|
||||||
goto Retry
|
goto Retry
|
||||||
}
|
}
|
||||||
|
|
||||||
return isError
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,7 @@ func TestPushToAndroidWrongToken(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Android Success count: 0, Failure count: 2
|
// Android Success count: 0, Failure count: 2
|
||||||
isError := PushToAndroid(req)
|
PushToAndroid(req)
|
||||||
assert.True(t, isError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPushToAndroidRightTokenForJSONLog(t *testing.T) {
|
func TestPushToAndroidRightTokenForJSONLog(t *testing.T) {
|
||||||
|
@ -80,8 +79,7 @@ func TestPushToAndroidRightTokenForJSONLog(t *testing.T) {
|
||||||
Message: "Welcome",
|
Message: "Welcome",
|
||||||
}
|
}
|
||||||
|
|
||||||
isError := PushToAndroid(req)
|
PushToAndroid(req)
|
||||||
assert.False(t, isError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPushToAndroidRightTokenForStringLog(t *testing.T) {
|
func TestPushToAndroidRightTokenForStringLog(t *testing.T) {
|
||||||
|
@ -98,8 +96,7 @@ func TestPushToAndroidRightTokenForStringLog(t *testing.T) {
|
||||||
Message: "Welcome",
|
Message: "Welcome",
|
||||||
}
|
}
|
||||||
|
|
||||||
isError := PushToAndroid(req)
|
PushToAndroid(req)
|
||||||
assert.False(t, isError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOverwriteAndroidAPIKey(t *testing.T) {
|
func TestOverwriteAndroidAPIKey(t *testing.T) {
|
||||||
|
@ -119,8 +116,7 @@ func TestOverwriteAndroidAPIKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FCM server error: 401 error: 401 Unauthorized (Wrong API Key)
|
// FCM server error: 401 error: 401 Unauthorized (Wrong API Key)
|
||||||
err := PushToAndroid(req)
|
PushToAndroid(req)
|
||||||
assert.False(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFCMMessage(t *testing.T) {
|
func TestFCMMessage(t *testing.T) {
|
||||||
|
@ -215,8 +211,7 @@ func TestCheckAndroidMessage(t *testing.T) {
|
||||||
TimeToLive: &timeToLive,
|
TimeToLive: &timeToLive,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := PushToAndroid(req)
|
PushToAndroid(req)
|
||||||
assert.False(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAndroidNotificationStructure(t *testing.T) {
|
func TestAndroidNotificationStructure(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue