mirror of
https://github.com/mollyim/monero-wallet-sdk.git
synced 2024-12-18 04:14:19 -05:00
lib: multiple fixes of async functions
This commit is contained in:
parent
5cf5c71b90
commit
698ae32ef2
@ -9,7 +9,7 @@ interface IWallet {
|
|||||||
void removeBalanceListener(in IBalanceListener listener);
|
void removeBalanceListener(in IBalanceListener listener);
|
||||||
oneway void save(in ParcelFileDescriptor destination);
|
oneway void save(in ParcelFileDescriptor destination);
|
||||||
oneway void resumeRefresh(boolean skipCoinbaseOutputs, in IRefreshCallback callback);
|
oneway void resumeRefresh(boolean skipCoinbaseOutputs, in IRefreshCallback callback);
|
||||||
void cancelRefresh();
|
oneway void cancelRefresh();
|
||||||
void setRefreshSince(long heightOrTimestamp);
|
oneway void setRefreshSince(long heightOrTimestamp);
|
||||||
void close();
|
void close();
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package im.molly.monero
|
|||||||
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
|
import kotlinx.coroutines.channels.onFailure
|
||||||
import kotlinx.coroutines.channels.trySendBlocking
|
import kotlinx.coroutines.channels.trySendBlocking
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.callbackFlow
|
import kotlinx.coroutines.flow.callbackFlow
|
||||||
@ -12,6 +13,8 @@ class MoneroWallet internal constructor(
|
|||||||
val remoteNodeClient: RemoteNodeClient?,
|
val remoteNodeClient: RemoteNodeClient?,
|
||||||
) : IWallet by wallet, AutoCloseable {
|
) : IWallet by wallet, AutoCloseable {
|
||||||
|
|
||||||
|
private val logger = loggerFor<MoneroWallet>()
|
||||||
|
|
||||||
val publicAddress: String = wallet.primaryAccountAddress
|
val publicAddress: String = wallet.primaryAccountAddress
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,11 +26,18 @@ class MoneroWallet internal constructor(
|
|||||||
|
|
||||||
override fun onBalanceChanged(txOuts: List<OwnedTxOut>?, checkedAtBlockHeight: Long) {
|
override fun onBalanceChanged(txOuts: List<OwnedTxOut>?, checkedAtBlockHeight: Long) {
|
||||||
lastKnownLedger = Ledger(publicAddress, txOuts!!, checkedAtBlockHeight)
|
lastKnownLedger = Ledger(publicAddress, txOuts!!, checkedAtBlockHeight)
|
||||||
trySendBlocking(lastKnownLedger)
|
sendLedger(lastKnownLedger)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRefresh(blockchainHeight: Long) {
|
override fun onRefresh(blockchainHeight: Long) {
|
||||||
trySendBlocking(lastKnownLedger.copy(checkedAtBlockHeight = blockchainHeight))
|
sendLedger(lastKnownLedger.copy(checkedAtBlockHeight = blockchainHeight))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendLedger(ledger: Ledger) {
|
||||||
|
trySend(ledger)
|
||||||
|
.onFailure {
|
||||||
|
logger.e("Too many ledger updates, channel capacity exceeded")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,10 +93,16 @@ class WalletNative private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cancelRefresh() = nativeCancelRefresh(handle)
|
override fun cancelRefresh() {
|
||||||
|
scope.launch(ioDispatcher) {
|
||||||
|
nativeCancelRefresh(handle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun setRefreshSince(blockHeightOrTimestamp: Long) {
|
override fun setRefreshSince(blockHeightOrTimestamp: Long) {
|
||||||
nativeSetRefreshSince(handle, blockHeightOrTimestamp)
|
scope.launch(ioDispatcher) {
|
||||||
|
nativeSetRefreshSince(handle, blockHeightOrTimestamp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -158,7 +164,12 @@ class WalletNative private constructor(
|
|||||||
|
|
||||||
private val pendingRequestLock = ReentrantLock()
|
private val pendingRequestLock = ReentrantLock()
|
||||||
|
|
||||||
@CalledByNative("wallet.cc")
|
/**
|
||||||
|
* Invoked by native code to make a cancellable remote call to a remote node.
|
||||||
|
*
|
||||||
|
* Caller must close [HttpResponse.body] upon completion of processing the response.
|
||||||
|
*/
|
||||||
|
@CalledByNative("http_client.cc")
|
||||||
private fun callRemoteNode(
|
private fun callRemoteNode(
|
||||||
method: String?,
|
method: String?,
|
||||||
path: String?,
|
path: String?,
|
||||||
@ -166,19 +177,26 @@ class WalletNative private constructor(
|
|||||||
body: ByteArray?,
|
body: ByteArray?,
|
||||||
): HttpResponse? = runBlocking {
|
): HttpResponse? = runBlocking {
|
||||||
pendingRequestLock.withLock {
|
pendingRequestLock.withLock {
|
||||||
pendingRequest = if (requestsAllowed) {
|
if (!requestsAllowed) {
|
||||||
async {
|
return@runBlocking null
|
||||||
remoteNodeClient?.request(HttpRequest(method, path, header, body))
|
|
||||||
}
|
|
||||||
} else null
|
|
||||||
}
|
|
||||||
runCatching {
|
|
||||||
pendingRequest?.await()
|
|
||||||
}.onFailure { throwable ->
|
|
||||||
if (throwable !is CancellationException) {
|
|
||||||
throw throwable
|
|
||||||
}
|
}
|
||||||
}.getOrNull()
|
pendingRequest = async {
|
||||||
|
remoteNodeClient?.request(HttpRequest(method, path, header, body))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
runCatching {
|
||||||
|
pendingRequest?.await()
|
||||||
|
}.onFailure { throwable ->
|
||||||
|
if (throwable is CancellationException) {
|
||||||
|
return@onFailure
|
||||||
|
}
|
||||||
|
logger.e("Error waiting for HTTP response", throwable)
|
||||||
|
throw throwable
|
||||||
|
}.getOrNull()
|
||||||
|
} finally {
|
||||||
|
pendingRequest = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
|
Loading…
Reference in New Issue
Block a user