0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Corda4.5】SendAllを使って、効率よく他ノードへメッセージを送ろう

Posted at

はじめに

最近、またCordaに浸かってます。
どーも、のぶこふです。

今回は、Corda4.5の新機能の目玉?でもある「SendAll」を紹介しようと思います。

SendAllとは?

Corda4.5で新規導入されたAPIです。
SendAllMapも併せて新規導入されていますが、今回は省略させていただきます。

これまでは、Send APIを使用して、各カウンターパーティに対して、一度だけメッセージを送っていました。
SendAllを使用することで、同様の処理を、効率よく実施することが可能になります。

Send/ReceiveやSendAll/ReceiveAllなど、メッセージの送受信の概略はコチラ

APIの詳細はドキュメントを参照ください
https://api.corda.net/api/corda-os/4.5/html/api/kotlin/corda/net.corda.core.flows/-flow-logic/send-all.html

ソースコード

[PR]今回も、サンプルのソースコードを用意してあります。
サクッと試してみたい方は、使ってみてください。

SendAllを使用するFlowと、Sendを使用するFlowの両者を用意してあるので、比較が行いやすいかと思います。

▼Github
※最新版ではTxを発行出来るようにしていますが、下記シナリオではTxは発行していません
https://github.com/nobkovskii/corda_sendall_sample

解説

基本的には、ソースコードをご覧いただければ分かるかと思いますが、簡単に解説を行います。
※解説に不要な箇所は削除してあります

  • Sessionを張ります。(①)
    • 今回はサンプルのため、宛先を固定しています。
  • SessionのSetとpayload(メッセージ)を引数に指定します。(②)
  • 受信側(Responder)は、payload(メッセージ)と同じ型を受信します。(③)
class Initiator(private val data: String) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        // String -> Party
        val b = toParty("O=PartyB,L=New York,C=US")
        val c = toParty("O=PartyC,L=New York,C=US")

        // sessionを張る
        // サンプルのため、宛先は固定
        //  --------------------------------- ①
        val sessionB = initiateFlow(b)
        val sessionC = initiateFlow(c)

        // sendAll(payload: Any, sessions: Set<FlowSession>, maySkipCheckpoint: Boolean = false): Unit
        //  --------------------------------- ②
        sendAll(data, setOf(sessionB, sessionC)) 
    }

    private fun toParty(name: String): Party {
        println(name)
        val x500Name = CordaX500Name.parse(name)
        return serviceHub.networkMapCache.getPeerByLegalName(x500Name) as Party
    }
}


@InitiatedBy(Initiator::class)
class Responder(val counterPartySession: FlowSession) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        // receiveAll(receiveType: Class<R>, sessions: List<FlowSession>, maySkipCheckpoint: Boolean = false): List<UntrustworthyData<R>>
        //  --------------------------------- ③
        val list = receiveAll(String::class.java, listOf(counterPartySession))
        list[0].unwrap { data -> println(data) }
    }
}

実行結果

続いて、実行結果です。
【注意】:今回のシナリオは、単にメッセージを送っているだけなので、本結果=TPSではありません。

▼実行環境

概要 説明
Corda OSS 4.5
PC Windows10 64bit(core i7,8GB)
Node A~E+Notaryの計6台。

▼シナリオ

PartyAから、他全ノードに対してメッセージを送る。
SendAllとSendをそれぞれ10回実行する。

▼実行結果

平均でも、瞬間風速でもSendAllのほうが優秀な結果が出ました。
※単位はms
image.png

↓のGifは、実際に動かしてみたアニメーションです。
裏で色々と起動していたため、処理時間が上記よりもかかっていますが、SendAllのほうが一瞬で各ノードへ送信しているように見えるのではないでしょうか。

配置
PartyA PartyD
PartyB PartyE
PartyC Notary

SendAll_Send_demo.gif

おわりに

今回はCorda4.5で新規導入された「FlowLogic.SendAll」を紹介しました。
Corda OSSではマルチスレッドでの動作が行えないので、こういったパフォーマンス向上系のAPIは嬉しいですね。

CordaのTPSにおいて、ボトルネックとなっているのは署名を集める(確認する)処理なので、今後に期待です。
※OSSのCollectSignatureFlowではsendを使用していた認識で、sendAllの使用箇所はほぼ無い

Githubにあげてあるソースコードには、sendとTx発行の両方が実行出来るようになっていますので、参考にしてみてください。

今回はここまでです。
ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?