Ensure the same txnId is reused if the Worker is started again.

This commit is contained in:
Benoit Marty 2021-07-21 11:43:47 +02:00
parent 49a44bd042
commit 7513e972d1
5 changed files with 32 additions and 14 deletions

View File

@ -23,12 +23,12 @@ import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.failure.shouldBeRetried import org.matrix.android.sdk.api.failure.shouldBeRetried
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.LocalEcho
import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.rest.ShareRequestCancellation import org.matrix.android.sdk.internal.crypto.model.rest.ShareRequestCancellation
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId
import org.matrix.android.sdk.internal.session.SessionComponent import org.matrix.android.sdk.internal.session.SessionComponent
import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker
import org.matrix.android.sdk.internal.worker.SessionWorkerParams import org.matrix.android.sdk.internal.worker.SessionWorkerParams
@ -43,6 +43,9 @@ internal class CancelGossipRequestWorker(context: Context,
override val sessionId: String, override val sessionId: String,
val requestId: String, val requestId: String,
val recipients: Map<String, List<String>>, val recipients: Map<String, List<String>>,
// The txnId for the sendToDevice request. Nullable for compatibility reason, but MUST always be provided
// to use the same value if this worker is retried.
val txnId: String? = null,
override val lastFailureMessage: String? = null override val lastFailureMessage: String? = null
) : SessionWorkerParams { ) : SessionWorkerParams {
companion object { companion object {
@ -51,6 +54,7 @@ internal class CancelGossipRequestWorker(context: Context,
sessionId = sessionId, sessionId = sessionId,
requestId = request.requestId, requestId = request.requestId,
recipients = request.recipients, recipients = request.recipients,
txnId = createUniqueTxnId(),
lastFailureMessage = null lastFailureMessage = null
) )
} }
@ -66,7 +70,8 @@ internal class CancelGossipRequestWorker(context: Context,
} }
override suspend fun doSafeWork(params: Params): Result { override suspend fun doSafeWork(params: Params): Result {
val localId = LocalEcho.createLocalEchoId() // (temporary code)
val txnId = params.txnId ?: createUniqueTxnId()
val contentMap = MXUsersDevicesMap<Any>() val contentMap = MXUsersDevicesMap<Any>()
val toDeviceContent = ShareRequestCancellation( val toDeviceContent = ShareRequestCancellation(
requestingDeviceId = credentials.deviceId, requestingDeviceId = credentials.deviceId,
@ -92,7 +97,7 @@ internal class CancelGossipRequestWorker(context: Context,
SendToDeviceTask.Params( SendToDeviceTask.Params(
eventType = EventType.ROOM_KEY_REQUEST, eventType = EventType.ROOM_KEY_REQUEST,
contentMap = contentMap, contentMap = contentMap,
transactionId = localId transactionId = txnId
) )
) )
cryptoStore.updateOutgoingGossipingRequestState(params.requestId, OutgoingGossipingRequestState.CANCELLED) cryptoStore.updateOutgoingGossipingRequestState(params.requestId, OutgoingGossipingRequestState.CANCELLED)

View File

@ -35,6 +35,7 @@ import org.matrix.android.sdk.internal.crypto.model.rest.GossipingDefaultContent
import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject
import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId
import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.SessionId
import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers import org.matrix.android.sdk.internal.util.MatrixCoroutineDispatchers
@ -356,7 +357,8 @@ internal class IncomingGossipingRequestManager @Inject constructor(
secretValue = secretValue, secretValue = secretValue,
requestUserId = request.userId, requestUserId = request.userId,
requestDeviceId = request.deviceId, requestDeviceId = request.deviceId,
requestId = request.requestId requestId = request.requestId,
txnId = createUniqueTxnId()
) )
cryptoStore.updateGossipingRequestState(request, GossipingRequestState.ACCEPTING) cryptoStore.updateGossipingRequestState(request, GossipingRequestState.ACCEPTING)
@ -376,13 +378,13 @@ internal class IncomingGossipingRequestManager @Inject constructor(
} }
request.share = { secretValue -> request.share = { secretValue ->
val params = SendGossipWorker.Params( val params = SendGossipWorker.Params(
sessionId = userId, sessionId = userId,
secretValue = secretValue, secretValue = secretValue,
requestUserId = request.userId, requestUserId = request.userId,
requestDeviceId = request.deviceId, requestDeviceId = request.deviceId,
requestId = request.requestId requestId = request.requestId,
txnId = createUniqueTxnId()
) )
cryptoStore.updateGossipingRequestState(request, GossipingRequestState.ACCEPTING) cryptoStore.updateGossipingRequestState(request, GossipingRequestState.ACCEPTING)

View File

@ -26,6 +26,7 @@ import org.matrix.android.sdk.internal.worker.WorkerParamsFactory
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -131,7 +132,8 @@ internal class OutgoingGossipingRequestManager @Inject constructor(
val params = SendGossipRequestWorker.Params( val params = SendGossipRequestWorker.Params(
sessionId = sessionId, sessionId = sessionId,
keyShareRequest = request as? OutgoingRoomKeyRequest, keyShareRequest = request as? OutgoingRoomKeyRequest,
secretShareRequest = request as? OutgoingSecretRequest secretShareRequest = request as? OutgoingSecretRequest,
txnId = createUniqueTxnId()
) )
cryptoStore.updateOutgoingGossipingRequestState(request.requestId, OutgoingGossipingRequestState.SENDING) cryptoStore.updateOutgoingGossipingRequestState(request.requestId, OutgoingGossipingRequestState.SENDING)
val workRequest = gossipingWorkManager.createWork<SendGossipRequestWorker>(WorkerParamsFactory.toData(params), true) val workRequest = gossipingWorkManager.createWork<SendGossipRequestWorker>(WorkerParamsFactory.toData(params), true)
@ -154,7 +156,8 @@ internal class OutgoingGossipingRequestManager @Inject constructor(
if (resend) { if (resend) {
val reSendParams = SendGossipRequestWorker.Params( val reSendParams = SendGossipRequestWorker.Params(
sessionId = sessionId, sessionId = sessionId,
keyShareRequest = request.copy(requestId = LocalEcho.createLocalEchoId()) keyShareRequest = request.copy(requestId = LocalEcho.createLocalEchoId()),
txnId = createUniqueTxnId()
) )
val reSendWorkRequest = gossipingWorkManager.createWork<SendGossipRequestWorker>(WorkerParamsFactory.toData(reSendParams), true) val reSendWorkRequest = gossipingWorkManager.createWork<SendGossipRequestWorker>(WorkerParamsFactory.toData(reSendParams), true)
gossipingWorkManager.postWork(reSendWorkRequest) gossipingWorkManager.postWork(reSendWorkRequest)

View File

@ -23,7 +23,6 @@ import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.failure.shouldBeRetried import org.matrix.android.sdk.api.failure.shouldBeRetried
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.LocalEcho
import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject
@ -31,6 +30,7 @@ import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyShareRequest
import org.matrix.android.sdk.internal.crypto.model.rest.SecretShareRequest import org.matrix.android.sdk.internal.crypto.model.rest.SecretShareRequest
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId
import org.matrix.android.sdk.internal.session.SessionComponent import org.matrix.android.sdk.internal.session.SessionComponent
import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker
import org.matrix.android.sdk.internal.worker.SessionWorkerParams import org.matrix.android.sdk.internal.worker.SessionWorkerParams
@ -46,6 +46,9 @@ internal class SendGossipRequestWorker(context: Context,
override val sessionId: String, override val sessionId: String,
val keyShareRequest: OutgoingRoomKeyRequest? = null, val keyShareRequest: OutgoingRoomKeyRequest? = null,
val secretShareRequest: OutgoingSecretRequest? = null, val secretShareRequest: OutgoingSecretRequest? = null,
// The txnId for the sendToDevice request. Nullable for compatibility reason, but MUST always be provided
// to use the same value if this worker is retried.
val txnId: String? = null,
override val lastFailureMessage: String? = null override val lastFailureMessage: String? = null
) : SessionWorkerParams ) : SessionWorkerParams
@ -58,7 +61,8 @@ internal class SendGossipRequestWorker(context: Context,
} }
override suspend fun doSafeWork(params: Params): Result { override suspend fun doSafeWork(params: Params): Result {
val localId = LocalEcho.createLocalEchoId() // (temporary code)
val txnId = params.txnId ?: createUniqueTxnId()
val contentMap = MXUsersDevicesMap<Any>() val contentMap = MXUsersDevicesMap<Any>()
val eventType: String val eventType: String
val requestId: String val requestId: String
@ -122,7 +126,7 @@ internal class SendGossipRequestWorker(context: Context,
SendToDeviceTask.Params( SendToDeviceTask.Params(
eventType = eventType, eventType = eventType,
contentMap = contentMap, contentMap = contentMap,
transactionId = localId transactionId = txnId
) )
) )
cryptoStore.updateOutgoingGossipingRequestState(requestId, OutgoingGossipingRequestState.SENT) cryptoStore.updateOutgoingGossipingRequestState(requestId, OutgoingGossipingRequestState.SENT)

View File

@ -23,7 +23,6 @@ import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.failure.shouldBeRetried import org.matrix.android.sdk.api.failure.shouldBeRetried
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.LocalEcho
import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter
@ -31,6 +30,7 @@ import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId
import org.matrix.android.sdk.internal.session.SessionComponent import org.matrix.android.sdk.internal.session.SessionComponent
import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker
import org.matrix.android.sdk.internal.worker.SessionWorkerParams import org.matrix.android.sdk.internal.worker.SessionWorkerParams
@ -48,6 +48,9 @@ internal class SendGossipWorker(context: Context,
val requestUserId: String?, val requestUserId: String?,
val requestDeviceId: String?, val requestDeviceId: String?,
val requestId: String?, val requestId: String?,
// The txnId for the sendToDevice request. Nullable for compatibility reason, but MUST always be provided
// to use the same value if this worker is retried.
val txnId: String? = null,
override val lastFailureMessage: String? = null override val lastFailureMessage: String? = null
) : SessionWorkerParams ) : SessionWorkerParams
@ -62,7 +65,8 @@ internal class SendGossipWorker(context: Context,
} }
override suspend fun doSafeWork(params: Params): Result { override suspend fun doSafeWork(params: Params): Result {
val localId = LocalEcho.createLocalEchoId() // (temporary code)
val txnId = params.txnId ?: createUniqueTxnId()
val eventType: String = EventType.SEND_SECRET val eventType: String = EventType.SEND_SECRET
val toDeviceContent = SecretSendEventContent( val toDeviceContent = SecretSendEventContent(
@ -127,7 +131,7 @@ internal class SendGossipWorker(context: Context,
SendToDeviceTask.Params( SendToDeviceTask.Params(
eventType = EventType.ENCRYPTED, eventType = EventType.ENCRYPTED,
contentMap = sendToDeviceMap, contentMap = sendToDeviceMap,
transactionId = localId transactionId = txnId
) )
) )
cryptoStore.updateGossipingRequestState( cryptoStore.updateGossipingRequestState(