Fix payments spinning forever.

This commit is contained in:
Cody Henthorne 2023-08-28 23:00:26 -04:00 committed by Greyson Parrelli
parent 6a21106347
commit b83080e2d7
5 changed files with 74 additions and 5 deletions

View file

@ -417,6 +417,16 @@ public final class PaymentTable extends DatabaseTable implements RecipientIdData
return payments;
}
public @NonNull List<UUID> getSubmittedIncomingPayments() {
return CursorExtensionsKt.readToList(
SQLiteDatabaseExtensionsKt.select(getReadableDatabase(), PAYMENT_UUID)
.from(TABLE_NAME)
.where(DIRECTION + " = ? AND " + STATE + " = ?", Direction.RECEIVED.serialize(), State.SUBMITTED.serialize())
.run(),
c -> UuidUtil.parseOrNull(CursorUtil.requireString(c, PAYMENT_UUID))
);
}
@AnyThread
public @NonNull LiveData<List<PaymentTransaction>> getAllLive() {
return LiveDataUtil.mapAsync(changeSignal, change -> getAll());

View file

@ -66,6 +66,7 @@ import org.thoughtcrime.securesms.migrations.PreKeysSyncMigrationJob;
import org.thoughtcrime.securesms.migrations.ProfileMigrationJob;
import org.thoughtcrime.securesms.migrations.ProfileSharingUpdateMigrationJob;
import org.thoughtcrime.securesms.migrations.RebuildMessageSearchIndexMigrationJob;
import org.thoughtcrime.securesms.migrations.RecheckPaymentsMigrationJob;
import org.thoughtcrime.securesms.migrations.RecipientSearchMigrationJob;
import org.thoughtcrime.securesms.migrations.StickerAdditionMigrationJob;
import org.thoughtcrime.securesms.migrations.StickerDayByDayMigrationJob;
@ -250,6 +251,7 @@ public final class JobManagerFactories {
put(ProfileMigrationJob.KEY, new ProfileMigrationJob.Factory());
put(ProfileSharingUpdateMigrationJob.KEY, new ProfileSharingUpdateMigrationJob.Factory());
put(RebuildMessageSearchIndexMigrationJob.KEY, new RebuildMessageSearchIndexMigrationJob.Factory());
put(RecheckPaymentsMigrationJob.KEY, new RecheckPaymentsMigrationJob.Factory());
put(RecipientSearchMigrationJob.KEY, new RecipientSearchMigrationJob.Factory());
put(StickerLaunchMigrationJob.KEY, new StickerLaunchMigrationJob.Factory());
put(StickerAdditionMigrationJob.KEY, new StickerAdditionMigrationJob.Factory());

View file

@ -652,10 +652,12 @@ object DataMessageProcessor {
} catch (e: MmsException) {
throw StorageFailedException(e, metadata.sourceServiceId.toString(), metadata.sourceDeviceId)
} finally {
ApplicationDependencies.getJobManager()
.startChain(PaymentTransactionCheckJob(uuid, queue))
.then(PaymentLedgerUpdateJob.updateLedger())
.enqueue()
SignalDatabase.runPostSuccessfulTransaction {
ApplicationDependencies.getJobManager()
.startChain(PaymentTransactionCheckJob(uuid, queue))
.then(PaymentLedgerUpdateJob.updateLedger())
.enqueue()
}
}
return null

View file

@ -137,9 +137,10 @@ public class ApplicationMigrations {
static final int EMOJI_SEARCH_INDEX_CHECK = 93;
static final int IDENTITY_FIX = 94;
static final int COPY_USERNAME_TO_SIGNAL_STORE = 95;
static final int RECHECK_PAYMENTS = 96;
}
public static final int CURRENT_VERSION = 95;
public static final int CURRENT_VERSION = 96;
/**
* This *must* be called after the {@link JobManager} has been instantiated, but *before* the call
@ -622,6 +623,10 @@ public class ApplicationMigrations {
jobs.put(Version.COPY_USERNAME_TO_SIGNAL_STORE, new CopyUsernameToSignalStoreMigrationJob());
}
if (lastSeenVersion < Version.RECHECK_PAYMENTS) {
jobs.put(Version.RECHECK_PAYMENTS, new RecheckPaymentsMigrationJob());
}
return jobs;
}

View file

@ -0,0 +1,50 @@
package org.thoughtcrime.securesms.migrations
import org.signal.core.util.logging.Log
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.jobmanager.Job
import org.thoughtcrime.securesms.jobs.PaymentLedgerUpdateJob
import org.thoughtcrime.securesms.jobs.PaymentTransactionCheckJob
/**
* Migration to recheck incoming payments that may have been missed due to db race.
*/
internal class RecheckPaymentsMigrationJob(
parameters: Parameters = Parameters.Builder().build()
) : MigrationJob(parameters) {
companion object {
const val KEY = "RecheckPaymentsMigrationJob"
val TAG = Log.tag(RecheckPaymentsMigrationJob::class.java)
}
override fun getFactoryKey(): String = KEY
override fun isUiBlocking(): Boolean = false
@Suppress("UsePropertyAccessSyntax")
override fun performMigration() {
val jobs: MutableList<Job> = SignalDatabase
.payments
.getSubmittedIncomingPayments()
.filterNotNull()
.map { PaymentTransactionCheckJob(it) }
.toMutableList()
Log.i(TAG, "Rechecking ${jobs.size} payments")
if (jobs.isNotEmpty()) {
jobs += PaymentLedgerUpdateJob.updateLedger()
}
ApplicationDependencies.getJobManager().addAll(jobs)
}
override fun shouldRetry(e: Exception): Boolean = false
class Factory : Job.Factory<RecheckPaymentsMigrationJob> {
override fun create(parameters: Parameters, serializedData: ByteArray?): RecheckPaymentsMigrationJob {
return RecheckPaymentsMigrationJob(parameters)
}
}
}