Updated on 2026-08-14

This commit is contained in:
Tangem 2022-03-24 20:44:54 +03:00
parent 67b0629d98
commit 228c37989d
3 changed files with 81 additions and 36 deletions

View file

@ -0,0 +1,64 @@
package com.tangem.tap.common
/**
[REDACTED_AUTHOR]
*/
open class Throttler<T>(
private val duration: Long,
) : Throttle<T> {
private val items: MutableMap<T, Long> = mutableMapOf()
override fun isStillThrottled(item: T): Boolean {
val inThrottlingUpTo = items[item] ?: return false
val diff = System.currentTimeMillis() - inThrottlingUpTo
return diff < 0
}
override fun updateThrottlingTo(item: T): T {
val now = System.currentTimeMillis()
val throttledUpTo = items[item] ?: 0L
if (throttledUpTo == 0L || throttledUpTo < now) {
val newTime = now + duration
items[item] = newTime
}
return item
}
open fun clear() {
items.clear()
}
}
class ThrottlerWithValues<T, V>(
duration: Long
) : Throttler<T>(duration), ValuesHolder<T, V> {
private val valuesHolder: MutableMap<T, V?> = mutableMapOf()
override fun setValue(item: T, value: V) {
valuesHolder[item] = value
}
override fun geValue(item: T): V? = valuesHolder[item]
override fun remove(item: T) {
valuesHolder.remove(item)
}
override fun clear() {
valuesHolder.clear()
super.clear()
}
}
interface Throttle<T> {
fun isStillThrottled(item: T): Boolean
fun updateThrottlingTo(item: T): T
}
interface ValuesHolder<K, V> {
fun setValue(item: K, value: V)
fun geValue(item: K): V?
fun remove(item: K)
}

View file

@ -3,6 +3,8 @@ package com.tangem.tap.domain
import com.tangem.blockchain.blockchains.solana.RentProvider
import com.tangem.blockchain.common.*
import com.tangem.common.services.Result
import com.tangem.tap.common.Throttler
import com.tangem.tap.common.ThrottlerWithValues
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
import com.tangem.tap.common.extensions.dispatchOnMain
import com.tangem.tap.common.extensions.safeUpdate
@ -39,32 +41,30 @@ class TapWalletManager {
store.state.globalState.configManager?.config?.blockchainSdkConfig ?: BlockchainSdkConfig()
}
private val walletManagersThrottler = Throttler<Blockchain>(10000)
private val walletManagersThrottler = ThrottlerWithValues<Blockchain, Result<Wallet>>(10000)
private val fiatRatesThrottler = Throttler<Currency>(60000)
suspend fun loadWalletData(walletManager: WalletManager) {
val blockchain = walletManager.wallet.blockchain
val result = if (walletManagersThrottler.isStillThrottled(blockchain)) {
delay(500)
Result.Success(walletManager.wallet)
walletManagersThrottler.geValue(blockchain)!!
} else {
walletManagersThrottler.updateThrottlingTo(blockchain)
walletManager.safeUpdate()
updateThrottlingForWalletManager(walletManager)
}
handleUpdateWalletResult(result, walletManager)
}
suspend fun updateWallet(walletManager: WalletManager, force: Boolean) {
val result = if (force) {
walletManager.safeUpdate()
updateThrottlingForWalletManager(walletManager)
} else {
val blockchain = walletManager.wallet.blockchain
if (walletManagersThrottler.isStillThrottled(blockchain)) {
delay(500)
Result.Success(walletManager.wallet)
walletManagersThrottler.geValue(blockchain)!!
} else {
walletManagersThrottler.updateThrottlingTo(blockchain)
walletManager.safeUpdate()
updateThrottlingForWalletManager(walletManager)
}
}
withContext(Dispatchers.Main) {
@ -75,7 +75,14 @@ class TapWalletManager {
store.dispatch(WalletAction.UpdateWallet.Failure(result.error.localizedMessage))
}
}
}
private suspend fun updateThrottlingForWalletManager(walletManager: WalletManager): Result<Wallet> {
val newResult = walletManager.safeUpdate()
val blockchain = walletManager.wallet.blockchain
walletManagersThrottler.updateThrottlingTo(blockchain)
walletManagersThrottler.setValue(blockchain, newResult)
return newResult
}
suspend fun loadFiatRate(fiatCurrency: FiatCurrencyName, wallet: Wallet) {
@ -248,6 +255,7 @@ class TapWalletManager {
}
private suspend fun handleUpdateWalletResult(result: Result<Wallet>, walletManager: WalletManager) {
walletManagersThrottler.setValue(walletManager.wallet.blockchain, result)
withContext(Dispatchers.Main) {
when (result) {
is Result.Success -> {
@ -327,31 +335,4 @@ class TapWalletManager {
fun Wallet.getFirstToken(): Token? {
return getTokens().toList().getOrNull(0)
}
class Throttler<T>(
private val duration: Long,
) {
private val items: MutableMap<T, Long> = mutableMapOf()
fun isStillThrottled(item: T): Boolean {
val inThrottlingUpTo = items[item] ?: return false
val diff = System.currentTimeMillis() - inThrottlingUpTo
return diff < 0
}
fun updateThrottlingTo(item: T): T {
val now = System.currentTimeMillis()
val throttledUpTo = items[item] ?: 0L
if (throttledUpTo == 0L || throttledUpTo < now) {
val newTime = now + duration
items[item] = newTime
}
return item
}
fun clear() {
items.clear()
}
}

View file

@ -204,7 +204,7 @@ private fun sendTransaction(
withContext(Dispatchers.Main) {
dispatch(WalletAction.UpdateWallet(walletManager.wallet.blockchain))
}
delay(10000)
delay(11000) // more than 10000 to avoid throttling
withContext(Dispatchers.Main) {
dispatch(WalletAction.UpdateWallet(walletManager.wallet.blockchain))
}