Corda Race Condition, Invoking some other flow from current flow, but input state is from current flow

99封情书 提交于 2020-01-01 19:56:14

问题


This question is raised while discussing Making asynchronous HTTP calls from flows

Suppose, we are implementing a Loan Application. After a LoanRequest is received, Corda flow will make an HTTP call to verify the request and we want to invoke other transaction automatically according to the result of HTTP call i.e to record ApprovedLoan or RejectedLoan State.

Now problem in this scenario is, ApprovedLoan or RejectedLoan transaction will need input state as LoanRequest. So we can't invoke the other flow from Acceptor of LoanRequest flow as the input state is not committed yet and thus resulting in race condition.

Any suggestion or examples on how this can be implemented would be appreciated.

Thanks.


回答1:


You need to commit the LoanRequest transaction to each node's storage first, before making the call in the acceptor to decide whether to approve or reject the request. You also need to use FlowLogic.waitForLedgerCommit to ensure you don't kick off the approval or rejection before the LoanRequest has been stored. Here's an example:

@InitiatingFlow
@StartableByRPC
class Initiator(val otherParty: Party) : FlowLogic<SignedTransaction>() {

    /**
     * The flow logic is encapsulated within the call() method.
     */
    @Suspendable
    override fun call(): SignedTransaction {
        val session = initiateFlow(otherParty)

        val fullySignedTx: SignedTransaction = TODO("Build fully signed transaction.")

        subFlow(FinalityFlow(fullySignedTx))

        session.send(fullySignedTx.id)
    }
}

@InitiatedBy(Initiator::class)
class Acceptor(val session: FlowSession) : FlowLogic<SignedTransaction>() {
    @Suspendable
    override fun call(): SignedTransaction {
        TODO("Response logic for building fully signed transaction.")

        val txId = session.receive<SecureHash>().unwrap { secureHash -> secureHash }

        waitForLedgerCommit(txId)

        val approve: Boolean = TODO("Make HTTP call to decide whether to approve or reject.")

        if (approve) {
            TODO("Response logic for building approval transaction.")
        } else {
            TODO("Response logic for building rejection transaction.")
        }
    }
}


来源:https://stackoverflow.com/questions/51627896/corda-race-condition-invoking-some-other-flow-from-current-flow-but-input-stat

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!