mirror of
https://github.com/corda/corda.git
synced 2025-02-12 05:35:50 +00:00
(cherry picked from commit 2da28c5)
This commit is contained in:
parent
9ecd82dc68
commit
d1574cd320
@ -742,3 +742,35 @@ We then update the progress tracker's current step as we progress through the fl
|
|||||||
:start-after: DOCSTART 18
|
:start-after: DOCSTART 18
|
||||||
:end-before: DOCEND 18
|
:end-before: DOCEND 18
|
||||||
:dedent: 12
|
:dedent: 12
|
||||||
|
|
||||||
|
|
||||||
|
Concurrency, Locking and Waiting
|
||||||
|
--------------------------------
|
||||||
|
This is an advanced topic. Because Corda is designed to:
|
||||||
|
|
||||||
|
* run many flows in parallel,
|
||||||
|
* may persist flows to storage and resurrect those flows much later,
|
||||||
|
* (in the future) migrate flows between JVMs,
|
||||||
|
|
||||||
|
flows should avoid use of locks and typically not even attempt to interact with objects shared between flows (except
|
||||||
|
``ServiceHub`` and other carefully crafted services such as Oracles. See :doc:`oracles`).
|
||||||
|
Locks will significantly reduce the scalability of the node, in the best case, and can cause the node to deadlock if they
|
||||||
|
remain locked across flow context switch boundaries (such as sending and receiving
|
||||||
|
from peers discussed above, and the sleep discussed below).
|
||||||
|
|
||||||
|
If you need activities that are scheduled, you should investigate the use of ``SchedulableState``.
|
||||||
|
However, we appreciate that Corda support for some more advanced patterns is still in the future, and if there is a need
|
||||||
|
for brief pauses in flows then you should use ``FlowLogic.sleep`` in place of where you might have used ``Thread.sleep``.
|
||||||
|
Flows should expressly not use ``Thread.sleep``, since this will prevent the node from processing other flows
|
||||||
|
in the meantime, significantly impairing the performance of the node.
|
||||||
|
Even ``FlowLogic.sleep`` is not to be used to create long running flows, since the Corda ethos is for short lived flows
|
||||||
|
(otherwise upgrading nodes or CorDapps is much more complicated), or as a substitute to using the ``SchedulableState`` scheduler.
|
||||||
|
|
||||||
|
Currently the ``finance`` package uses ``FlowLogic.sleep`` to make several attempts at coin selection, where necessary,
|
||||||
|
when many states are soft locked and we wish to wait for those, or other new states in their place, to become unlocked.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/AbstractCashSelection.kt
|
||||||
|
:language: kotlin
|
||||||
|
:start-after: DOCSTART CASHSELECT 1
|
||||||
|
:end-before: DOCEND CASHSELECT 1
|
||||||
|
:dedent: 8
|
||||||
|
@ -12,7 +12,10 @@ import net.corda.core.node.ServiceHub
|
|||||||
import net.corda.core.node.services.StatesNotAvailableException
|
import net.corda.core.node.services.StatesNotAvailableException
|
||||||
import net.corda.core.utilities.*
|
import net.corda.core.utilities.*
|
||||||
import net.corda.finance.contracts.asset.Cash
|
import net.corda.finance.contracts.asset.Cash
|
||||||
import java.sql.*
|
import java.sql.Connection
|
||||||
|
import java.sql.DatabaseMetaData
|
||||||
|
import java.sql.ResultSet
|
||||||
|
import java.sql.SQLException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
@ -101,6 +104,7 @@ abstract class AbstractCashSelection {
|
|||||||
withIssuerRefs: Set<OpaqueBytes> = emptySet()): List<StateAndRef<Cash.State>> {
|
withIssuerRefs: Set<OpaqueBytes> = emptySet()): List<StateAndRef<Cash.State>> {
|
||||||
val stateAndRefs = mutableListOf<StateAndRef<Cash.State>>()
|
val stateAndRefs = mutableListOf<StateAndRef<Cash.State>>()
|
||||||
|
|
||||||
|
// DOCSTART CASHSELECT 1
|
||||||
for (retryCount in 1..MAX_RETRIES) {
|
for (retryCount in 1..MAX_RETRIES) {
|
||||||
if (!attemptSpend(services, amount, lockId, notary, onlyFromIssuerParties, withIssuerRefs, stateAndRefs)) {
|
if (!attemptSpend(services, amount, lockId, notary, onlyFromIssuerParties, withIssuerRefs, stateAndRefs)) {
|
||||||
log.warn("Coin selection failed on attempt $retryCount")
|
log.warn("Coin selection failed on attempt $retryCount")
|
||||||
@ -116,6 +120,7 @@ abstract class AbstractCashSelection {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// DOCEND CASHSELECT 1
|
||||||
return stateAndRefs
|
return stateAndRefs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user