Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

VerStixの紹介

611 views

Published on

PharoとVert.xをつなぐライブラリVerStixの紹介です

Published in: Software
  • Be the first to comment

VerStixの紹介

  1. 1. VerStix Pharo Smalltalk と Vert.x 第102回Smalltalk勉強会 合同会社ソフトウメヤ 梅澤真史
  2. 2. VerStixとは ● Vert.xと連携するためのクライアントライブラリ ○ https://github.com/mumez/VerStix ● 簡潔かつリアクティブな形で Pharoと外部サービスとの連携を行える
  3. 3. Vert.x ● リアクティブなシステム開発のためのツールキット ○ http://vertx.io/ ● 非同期APIでWeb, DB, MQ, 認証などのサービスと連携 ○ Verticle (いわゆるActorのようなもの) ○ EventBus経由で通信 ● マルチ言語をサポート(Java, JavaScript, Groovy, Ruby, Ceylon, Kotlin, Scala)
  4. 4. Vert.x EventBus ● Vert.xの根幹となる非同期通信機構 ○ http://vertx.io/docs/vertx-core/java/#event_bus ● イベントをpeer-to-peer、pub-subなど様々な形式で送信可能 ● イベントの配送順序は保証するが厳密な配送保証はしない ● TCP EventBus Bridgeにより、JVM言語以外との連携も可能 ○ https://github.com/vert-x3/vertx-tcp-eventbus-bridge
  5. 5. TCP EventBus Bridge Clients ● Swift, C++, C#, Python, Goなど ○ https://github.com/vert-x3/vertx-awesome#vertx-event-bus-clients ● Smalltalk版がVerStixという位置づけ ○ 自動再接続や簡易なコネクションプールも提供 ○ VerStix-Core パッケージのみ ■ わずか6クラスでできている ● Stick上に作られているため
  6. 6. TCP EventBus Bridge のプロトコル ● HTTPよりも簡単 ○ TCPのSocketでJSONを送るだけ ○ 4バイトのメッセージ長+JSON ● JSONの形式 ○ address ○ headers ○ body ○ メッセージ種別 (send, publish, register, unregister) ○ (replyAddress)
  7. 7. Vert.xのインストール ● SDKMAN が楽 ○ 様々なプラットフォームに対応 ○ JDM系のSDKのインストールをまとめて行える ● インストール後は vertx コマンドが使えるようになる $ sdk install vertx
  8. 8. VerStixのインストール ● Catalog Browserから ○ 'verstix'で検索し、'install stable version' ● あるいはMetacelloでロード Metacello new smalltalkhubUser: 'Pharo' project: 'MetaRepoForPharo60'; configuration: 'VerStix'; version: #stable; get; load.
  9. 9. サンプルのVerticleを起動 ● 動作確認用のサンプルVerticle(groovy)を入手 ○ https://github.com/mumez/VerStix/blob/master/example/ TcpEventBusBridgeEchoServer.groovy ■ helloイベントの受信、echoイベントの送受信ができる ● vertxコマンドでVerticleを起動 ○ --instances <n> で複数起動もできる(ラウンドロビン) ○ --ha でクラスタリングもできる(プロセス間でRR) $ vertx run TcpEventBusBridgeEchoServer.groovy
  10. 10. VerStixからのイベント送信 ● 接続 eventBus := VsEventBus host: 'localhost' port: 7000. eventBus connect. ● 'echo'イベントの送信 eventBus send: {'value'->'HELLO from Smalltalk'} to: 'echo'. $ got: {"value":"HELLO from Smalltalk"} => コンソールに表示される
  11. 11. コールバックの指定 ● 送信時にcallbackの指定が可能 ○ サーバでの処理が終わると非同期で呼び出される ● 'echo'なので送信したメッセージのbodyそのものが 返ってきてインスペクタが開く eventBus send: {'value'-> Time now asString} to: 'echo'   callback: [:msg | msg body inspect].
  12. 12. Pub/Subをしてみる ● VsEventBus>>subscribe:callback:でイベントハンドラを登録 ● VsEventBus>>publish:to:でイベントをブロードキャスト ● 複数のPharoイメージで試してみましょう eventBus subscribe: 'echo' callback: [:msg | msg body inspect]. eventBus publish: {'value'-> Time now asString} to: 'echo'.
  13. 13. Goとつないでみる ● vxc (Goで書かれたVert.x EventBusのCLI)を使用 ○ https://github.com/cinterloper/vxc ● echoイベントをsubscribeさせてみる ● Pharoからpublishすると $ go run app.go -l -n echo $ {"value":"1:39:31.546674 pm"}
  14. 14. Vert.x側のイベントハンドラ ● イベントに対するConsumerを指定 vertx.eventBus().consumer("echo", {msg -> //msg.reply(new JsonObject().put("value", "Hello); msg.reply(msg.body()); }); ● JsonObjectにしてreply()で値を返す
  15. 15. EventBusBridgeの起動 ● 生成時にBridgeOptionsで送受信するイベントを設定 TcpEventBusBridge bridge = TcpEventBusBridge.create(vertx, new BridgeOptions() .addInboundPermitted(new PermittedOptions().setAddress("hello")) .addInboundPermitted(new PermittedOptions().setAddress("echo")) .addOutboundPermitted(new PermittedOptions().setAddress("echo"))); bridge.listen(7000, {res -> System.out.println("Ready: "+ bridge)}); ● listen()で起動
  16. 16. 応用例: bolt.x ● Neo4jの純正Bolt Protocol DriverをVerStixから呼び出す ○ サーバ (Java) ■ https://github.com/mumez/bolt.x ○ クライアント (Pharo) ■ http://smalltalkhub.com/#!/~MasashiUmezawa/Boltx ● PharoからJavaのBolt DriverによるNeo4jへのアクセスが可能 ● 非同期APIが使えるようになる ○ REST APIでは提供されていない
  17. 17. bolt.xのインストール (サーバ側) $ $ ./bin/neo4j console ● Neo4jを入手 ○ https://neo4j.com/download/community-edition/ ■ tarballを展開して起動 ○ http://localhost:7474/browser/ にアクセスし、サンプルのMovie Graphを作成しておく ● Githubからbolt.xをcloneしてredeploy.shを起動 $ $ bash redeploy.sh
  18. 18. bolt.xのインストール (クライアント側) Gofer new url: 'http://smalltalkhub.com/mc/MasashiUmezawa/Boltx/main'; package: 'ConfigurationOfBoltx'; load. (Smalltalk at: #ConfigurationOfBoltx) load ● Goferでいつものやつ
  19. 19. 非同期APIでのCypher実行 client := BxCypherClient host: 'localhost' port: 7000. req := client asyncQueryByCypher: 'MATCH (n:Movie{released:$y}) RETURN n' params: {'y'->2000}. ● asyncQueryByCypher:paramsを使う ● ifNext:で結果をpushでrowごとに取得 req ifNext: [:val | Transcript cr; show: val ]. ● ifDone:で結果をまとめて取得 req ifDone: [ :vals | vals inspect ].
  20. 20. 非同期で書き込み client := BxCypherClient host: 'localhost' port: 7000. req := client writeByCypher: ' MERGE (a:Person {name: $name1}) MERGE (b:Person {name: $name2}) MERGE (a)-[r:KNOWS]->(b) ' params: {'name1'->'test1'. 'name2'->'test2'}. ● writeByCypher:params:を使う ● ifFailed:でエラーがあった時に通知 req ifFailed: [ :error | error inspect ]
  21. 21. 非同期でバルク書き込み client := BxCypherClient host: 'localhost' port: 7000. req := client writeBySameCypher: ' MERGE (a:Person {name: $name1}) MERGE (b:Person {name: $name2}) MERGE (a)-[r:KNOWS]->(b) ' paramsArray: ((1 to: 1000) collect: [:idx | {'name1'->idx asString. 'name2'->(idx+1) asString}]). ● 同一のCypherでパラメータだけを変更して大量書き込み
  22. 22. 同期APIとの比較 graphDb := N4GraphDb new. req := client queryByCyphers:( (1 to: 1000) collect: [ :idx | { 'MERGE (a:Person {name: $name1}) MERGE (b:Person {name: $name2}) MERGE (a)-[r:KNOWS]->(b)'. {'name1'->'test1'. 'name2'->'test2'} }]). ● Neo4reStの場合 ○ 処理が終わるまでPharo側はブロック ○ 同一の重複したCypherを送っていて無駄が多い
  23. 23. Vert.x側での留意点 vertx.<JsonObject>executeBlocking(future -> { basicExecute(msg, future); }, true, res -> { msg.reply(res.result()); }); ● 各処理がブロッキングで止まらないようにする ○ 外部DB等の同期APIを呼び出す時に注意
  24. 24. その他の応用例 ● EventBus経由でVert.x JDBC Clientを使えるようにする ○ PharoからMySQLやOracleに接続できるようになる ● EventBus経由で認証系APIとつなぐ ○ PharoからJWTやShiroなどの利用が可能になる
  25. 25. まとめ ● VerStixを使うと簡単なイベント送信のAPIで、既存のサービ スを連携させることができる ● 同期のみのAPIを非同期化したり、何かと手厚いJavaのSDK やドライバをPharoから手軽に利用したりするには有効

×