Initiating a flow session from a flow that is annoted with InitiatedBy to a flow which is also InitiatedBy

回眸只為那壹抹淺笑 提交于 2019-12-23 05:17:05

问题


Is it possible to initiate a flow session from a flow that is annoted with InitiatedBy to a flow which is also annoted with InitiatedBy?

For example:

@InitiatingFlow Class FlowA

@InitiatedBy(FlowA.class) Class FlowB

@InitiatedBy(FlowB.class) Class FlowC

is it possible to achieve sequence of flow session like: A->B->C ?


回答1:


Yes, this is possible, as follows:

@InitiatingFlow
@StartableByRPC
class Initiator(val firstCounterparty: Party, val secondCounterparty: Party) : FlowLogic<Int>() {
    override val progressTracker = ProgressTracker()

    @Suspendable
    override fun call(): Int {
        val flowSession = initiateFlow(firstCounterparty)
        flowSession.send(secondCounterparty)
        return flowSession.receive<Int>().unwrap { it }
    }
}

@InitiatingFlow
@InitiatedBy(Initiator::class)
class Responder(val flowSession: FlowSession) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        val secondCounterparty = flowSession.receive<Party>().unwrap { it }
        val newFlowSession = initiateFlow(secondCounterparty)
        val int = newFlowSession.receive<Int>().unwrap { it }
        flowSession.send(int)
    }
}

@InitiatingFlow
@InitiatedBy(Responder::class)
class ResponderResponder(val flowSession: FlowSession) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        flowSession.send(3)
    }
}

However, there is one major caveat. In Corda 3.x, you can't have two FlowSessions with the same counterparty in the same flow. So either you need to disallow the case where A -> B -> A, as follows:

@InitiatingFlow
@StartableByRPC
class Initiator(val firstCounterparty: Party, val secondCounterparty: Party) : FlowLogic<Int>() {
    override val progressTracker = ProgressTracker()

    @Suspendable
    override fun call(): Int {
        if (secondCounterparty == ourIdentity) {
            throw FlowException("In Corda 3.x, you can't have two flow sessions with the same party.")
        }

        val flowSession = initiateFlow(firstCounterparty)
        flowSession.send(secondCounterparty)
        return flowSession.receive<Int>().unwrap { it }
    }
}

@InitiatingFlow
@InitiatedBy(Initiator::class)
class Responder(val flowSession: FlowSession) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        val secondCounterparty = flowSession.receive<Party>().unwrap { it }
        if (secondCounterparty == flowSession.counterparty) {
            throw FlowException("In Corda 3.x, you can't have two flow sessions with the same party.")
        }

        val newFlowSession = initiateFlow(secondCounterparty)
        val int = newFlowSession.receive<Int>().unwrap { it }
        flowSession.send(int)
    }
}

@InitiatingFlow
@InitiatedBy(Responder::class)
class ResponderResponder(val flowSession: FlowSession) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        flowSession.send(3)
    }
}

Or you need to drop into an InitiatingFlow subflow in Responder before starting the flow that starts ResponderResponder, as follows:

@InitiatingFlow
@StartableByRPC
class Initiator(val firstCounterparty: Party, val secondCounterparty: Party) : FlowLogic<Int>() {
    override val progressTracker = ProgressTracker()

    @Suspendable
    override fun call(): Int {
        val flowSession = initiateFlow(firstCounterparty)
        flowSession.send(secondCounterparty)
        return flowSession.receive<Int>().unwrap { it }
    }
}

@InitiatingFlow
@InitiatedBy(Initiator::class)
class Responder(val flowSession: FlowSession) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        val secondCounterparty = flowSession.receive<Party>().unwrap { it }
        val int = subFlow(ResponderInitiator(secondCounterparty))
        flowSession.send(int)
    }
}

@InitiatingFlow
class ResponderInitiator(val counterparty: Party) : FlowLogic<Int>() {
    @Suspendable
    override fun call(): Int {
        val flowSession = initiateFlow(counterparty)
        return flowSession.receive<Int>().unwrap { it }
    }
}

@InitiatingFlow
@InitiatedBy(ResponderInitiator::class)
class ResponderResponder(val flowSession: FlowSession) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        flowSession.send(3)
    }
}


来源:https://stackoverflow.com/questions/53447038/initiating-a-flow-session-from-a-flow-that-is-annoted-with-initiatedby-to-a-flow

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