Utilize re-entrant locking for in app payments instead of synchronized blocks.

This commit is contained in:
Alex Hart
2024-11-08 10:48:03 -04:00
committed by Greyson Parrelli
parent a79b4c3ba0
commit ed24fd0c4b
16 changed files with 61 additions and 25 deletions

View File

@@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.util.rx.RxStore
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription
import java.util.Locale
import kotlin.concurrent.withLock
class InternalDonorErrorConfigurationViewModel : ViewModel() {
@@ -101,7 +102,7 @@ class InternalDonorErrorConfigurationViewModel : ViewModel() {
fun save(): Completable {
val snapshot = store.state
val saveState = Completable.fromAction {
synchronized(InAppPaymentSubscriberRecord.Type.DONATION) {
InAppPaymentSubscriberRecord.Type.DONATION.lock.withLock {
when {
snapshot.selectedBadge?.isGift() == true -> handleGiftExpiration(snapshot)
snapshot.selectedBadge?.isBoost() == true -> handleBoostExpiration(snapshot)
@@ -116,7 +117,7 @@ class InternalDonorErrorConfigurationViewModel : ViewModel() {
fun clearErrorState(): Completable {
return Completable.fromAction {
synchronized(InAppPaymentSubscriberRecord.Type.DONATION) {
InAppPaymentSubscriberRecord.Type.DONATION.lock.withLock {
SignalStore.inAppPayments.setExpiredBadge(null)
SignalStore.inAppPayments.setExpiredGiftBadge(null)
SignalStore.inAppPayments.unexpectedSubscriptionCancelationReason = null

View File

@@ -56,6 +56,7 @@ import org.whispersystems.signalservice.internal.push.exceptions.InAppPaymentPro
import java.security.SecureRandom
import java.util.Currency
import java.util.Optional
import java.util.concurrent.locks.Lock
import kotlin.jvm.optionals.getOrNull
import kotlin.time.Duration
import kotlin.time.Duration.Companion.days
@@ -231,10 +232,11 @@ object InAppPaymentsRepository {
/**
* Returns the object to utilize as a mutex for recurring subscriptions.
*/
fun resolveMutex(inAppPaymentId: InAppPaymentTable.InAppPaymentId): Any {
@WorkerThread
fun resolveLock(inAppPaymentId: InAppPaymentTable.InAppPaymentId): Lock {
val payment = SignalDatabase.inAppPayments.getById(inAppPaymentId) ?: error("Not found")
return payment.type.requireSubscriberType()
return payment.type.requireSubscriberType().lock
}
/**

View File

@@ -214,7 +214,7 @@ object RecurringInAppPaymentRepository {
subscriptionLevel,
subscriber.currency.currencyCode,
levelUpdateOperation.idempotencyKey.serialize(),
subscriberType
subscriberType.lock
)
}
.flatMapCompletable {