Fix a race condition: Push can be received before the Gateway API returns

This commit is contained in:
Benoit Marty 2021-04-16 16:13:16 +02:00
parent 19427fbfec
commit c6a493848e
2 changed files with 15 additions and 5 deletions

View File

@ -66,12 +66,13 @@ interface PushersService {
/** /**
* Directly ask the push gateway to send a push to this device * Directly ask the push gateway to send a push to this device
* If successful, the push gateway has accepted the request. In this case, the app should receive a Push with the provided eventId.
* In case of error, PusherRejected will be thrown. In this case it means that the pushkey is not valid.
*
* @param url the push gateway url (full path) * @param url the push gateway url (full path)
* @param appId the application id * @param appId the application id
* @param pushkey the FCM token * @param pushkey the FCM token
* @param eventId the eventId which will be sent in the Push message. Use a fake eventId. * @param eventId the eventId which will be sent in the Push message. Use a fake eventId.
* @param callback callback to know if the push gateway has accepted the request. In this case, the app should receive a Push with the provided eventId.
* In case of error, PusherRejected failure can happen. In this case it means that the pushkey is not valid.
*/ */
suspend fun testPush(url: String, suspend fun testPush(url: String,
appId: String, appId: String,

View File

@ -42,8 +42,10 @@ class TestPushFromPushGateway @Inject constructor(private val context: AppCompat
: TroubleshootTest(R.string.settings_troubleshoot_test_push_loop_title) { : TroubleshootTest(R.string.settings_troubleshoot_test_push_loop_title) {
private var action: Job? = null private var action: Job? = null
private var pushReceived: Boolean = false
override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) { override fun perform(activityResultLauncher: ActivityResultLauncher<Intent>) {
pushReceived = false
val fcmToken = FcmHelper.getFcmToken(context) ?: run { val fcmToken = FcmHelper.getFcmToken(context) ?: run {
status = TestStatus.FAILED status = TestStatus.FAILED
return return
@ -55,9 +57,15 @@ class TestPushFromPushGateway @Inject constructor(private val context: AppCompat
status = result status = result
.fold( .fold(
{ {
// Wait for the push to be received if (pushReceived) {
description = stringProvider.getString(R.string.settings_troubleshoot_test_push_loop_waiting_for_push) // Push already received (race condition)
TestStatus.RUNNING description = stringProvider.getString(R.string.settings_troubleshoot_test_push_loop_success)
TestStatus.SUCCESS
} else {
// Wait for the push to be received
description = stringProvider.getString(R.string.settings_troubleshoot_test_push_loop_waiting_for_push)
TestStatus.RUNNING
}
}, },
{ {
description = if (it is PushGatewayFailure.PusherRejected) { description = if (it is PushGatewayFailure.PusherRejected) {
@ -73,6 +81,7 @@ class TestPushFromPushGateway @Inject constructor(private val context: AppCompat
} }
override fun onPushReceived() { override fun onPushReceived() {
pushReceived = true
description = stringProvider.getString(R.string.settings_troubleshoot_test_push_loop_success) description = stringProvider.getString(R.string.settings_troubleshoot_test_push_loop_success)
status = TestStatus.SUCCESS status = TestStatus.SUCCESS
} }