【发布时间】:2018-05-21 20:42:57
【问题描述】:
在 Corda 中,如何从流中发出异步 HTTP 请求?是否有 API 可以在等待 HTTP 调用的响应时暂停流,或者提供回调的方法?
【问题讨论】:
标签: corda
在 Corda 中,如何从流中发出异步 HTTP 请求?是否有 API 可以在等待 HTTP 调用的响应时暂停流,或者提供回调的方法?
【问题讨论】:
标签: corda
Corda 目前不提供一种机制来发出异步 HTTP 请求,然后在等待响应时暂停流,或提供将在收到响应时调用的回调。
相反,建议您在启动流之前发出 HTTP 请求,然后在实例化流时将响应作为参数传入。
有时,这是不可能的。例如,自动启动的响应流可能需要 HTTP 请求,也可能取决于从对方收到的消息的内容。
在这种情况下,您仍然可以支持这种工作流程,如下所示。假设您正在为贷款申请编写一个 CorDapp,表示为 LoanApplicationStates。如果没有 HTTP 调用,响应者不知道是否接受贷款申请。
流程将创建一个UnacceptedLoanApplicationState,而不是直接创建LoanApplicationState,响应者将其存储在他们的分类帐中。一旦流程结束,响应者可以在流程框架之外进行 HTTP 调用。根据 HTTP 调用的结果,响应者将启动创建事务以将 UnacceptedLoanApplicationState 转换为 LoanApplicationState 的批准流程,或者启动拒绝流程以使用 UnacceptedLoanApplicationState 状态而不发出接受LoanApplicationState。
或者,您可以向LoanApplicationState 添加一个状态字段,指定贷款是否被批准。最初,贷款状态将字段设置为未批准。然后,根据 HTTP 请求的结果,响应者将启动两个流程之一来更新 LoanApplicationState,将其更新为已批准或已拒绝状态。
【讨论】:
CordaRPCOps.vaultTrackBy 来检查何时注册了新的未接受的贷款申请。
Corda 使用quasar fibers 进行类似同步(异步)的调用。幸运的是,quasar 支持java's Future 和guava's ListenableFuture。
基于此,您可以创建一个这样的流
@InitiatingFlow
class ListenableFutureFlow<V>(val futureFn: () -> ListenableFuture<V>,
override val progressTracker: ProgressTracker) : FlowLogic<V>() {
constructor(futureFn: () -> ListenableFuture<V>) : this(futureFn, tracker())
companion object {
object EXECUTING_FUTURE: ProgressTracker.Step("Executing future call inside fiber")
fun tracker() = ProgressTracker(EXECUTING_FUTURE)
}
@Suspendable
override fun call(): V {
progressTracker.currentStep = EXECUTING_FUTURE
return AsyncListenableFuture.get(futureFn())
}
}
你可以这样使用它:
val asyncResponse = subFlow(ListenableFutureFlow { myAsyncCall(param1, param2) })
这不是最好的解决方案,但至少可以与 corda 的基础架构一起使用 :)
让我知道它是否适合你!
【讨论】: