CORDA-1040 docs for FlowLogic.sleep (#2625)

This commit is contained in:
Rick Parker 2018-02-26 16:07:40 +00:00 committed by GitHub
parent b91ef43e0f
commit 2da28c574e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 1 deletions

View File

@ -744,3 +744,35 @@ We then update the progress tracker's current step as we progress through the fl
:start-after: DOCSTART 18
:end-before: DOCEND 18
: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

View File

@ -12,7 +12,10 @@ import net.corda.core.node.ServiceHub
import net.corda.core.node.services.StatesNotAvailableException
import net.corda.core.utilities.*
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.concurrent.atomic.AtomicReference
import java.util.concurrent.locks.ReentrantLock
@ -101,6 +104,7 @@ abstract class AbstractCashSelection {
withIssuerRefs: Set<OpaqueBytes> = emptySet()): List<StateAndRef<Cash.State>> {
val stateAndRefs = mutableListOf<StateAndRef<Cash.State>>()
// DOCSTART CASHSELECT 1
for (retryCount in 1..MAX_RETRIES) {
if (!attemptSpend(services, amount, lockId, notary, onlyFromIssuerParties, withIssuerRefs, stateAndRefs)) {
log.warn("Coin selection failed on attempt $retryCount")
@ -116,6 +120,7 @@ abstract class AbstractCashSelection {
break
}
}
// DOCEND CASHSELECT 1
return stateAndRefs
}