web版lindaによる実世界コンピューティング

65
WebLindaによる 実世界コンピューティング @shokai プログラミングシンポジウム 2014

Upload: sho-hashimoto

Post on 30-Nov-2014

2.276 views

Category:

Technology


3 download

DESCRIPTION

プログラミングシンポジウム2014夏の発表資料です 発表時の内容に加えて、質疑応答やtwitterでの反応への返答なども含めて更新しています。

TRANSCRIPT

Page 1: Web版Lindaによる実世界コンピューティング

Web版Lindaによる

実世界コンピューティング

@shokai

プログラミングシンポジウム 2014夏

Page 2: Web版Lindaによる実世界コンピューティング

自己紹介

•@shokai

•橋本 翔

•慶應SFC増井研

Page 3: Web版Lindaによる実世界コンピューティング

実世界コンピューティングとは

電子工作とかセンサーとか使うやつのこと

(大雑把に言うと)

Page 4: Web版Lindaによる実世界コンピューティング

実世界コンピューティングとWebを接続したい

色んな言語・デバイスで接続したい 安定して動かして毎日使いたい 常に拡張しやすくしておきたい

!

という便利ツールが出来たので紹介する発表に来ました

Page 5: Web版Lindaによる実世界コンピューティング

Lindaとは?

Page 6: Web版Lindaによる実世界コンピューティング

Lindaとは?•プロセス間の共有メモリでデータを読み書きして並列・分散処理する

• 1990年ごろ流行った、らしい • out (書き込み) • rd (読み出す)、rdp (ノンブロックで読み出す) • in (読み出しつつ削除)、inp (ノンブロックで削除) • だけで大抵の処理が書ける

Tuple Space Tuple

Page 7: Web版Lindaによる実世界コンピューティング

Lindaとは?(2)TupleSpace["買い物", "牛乳"]

["user", "shokai"]["買い物", "鳥肉"]

Tuple["買い物", "卵"]

書き込み

["買い物", "肉"]

読み出し

• TupleSpaceにTupleを読み書きする •配列の前方一致で読み出す • [“買い物"] で読みだすと、どれかが取れる

何でも書き込める

Tuple

Page 8: Web版Lindaによる実世界コンピューティング

Lindaとは?(3)•既存の実装 • C、Java、Ruby、Python、Lua、Erlangなどで実装されている

•画像処理のパイプライン等 !

•それぞれプロトコルが違うので相互接続できない問題がある

Page 9: Web版Lindaによる実世界コンピューティング

Node.js + Socket.IO でLindaを作った

https://npmjs.org/linda

元々Rubyで実装していたが 疲れたのでNodeにした

Page 10: Web版Lindaによる実世界コンピューティング

インストール

% npm install linda -g

-gでグローバルインストールすると 実行コマンドも入って便利!

Page 11: Web版Lindaによる実世界コンピューティング

Linda使用例

Page 12: Web版Lindaによる実世界コンピューティング

研究室間 センサ情報通知

•1. 照度センサTuple • 2. 明るくなった/暗くなったTuple

• 3. Sayしろ/Yoしろ/チャットに通知しろTuple

• 増井研、部屋が分かれてるので一体感を出したい • shokai自宅も参加している

という風にTupleの読み書き連鎖で連動する

Page 13: Web版Lindaによる実世界コンピューティング

近づいたらドアが開く•0. iBeaconで接近検知 • 1. 誰がどこにいるかTuple • 2. ドア開けろTuple • 3. サーボ回しましたTuple • 4. sayしろ/チャット通知しろTuple

iBeaconから直接ドア開け しないので 拡張しやすい

Page 14: Web版Lindaによる実世界コンピューティング

チャットでも見れる

Page 15: Web版Lindaによる実世界コンピューティング

起きたら通知•0. 起きる • 1. Jawbone UP24で睡眠Tupleを書き込み

• 2. チャット通知Tuple !

•寝坊したら起こしてもらえる可能性高い

Page 16: Web版Lindaによる実世界コンピューティング

Terminalで作業→Hue電球

•0. shellのヒストリ追う • 1. 作業したTuple、git commitしたぞTuple等

• 2. Hueを少し色変える • 3. 何もしてないと段々暗くなる

俺がプログラミングがんばってる感が自宅に伝わる

Page 17: Web版Lindaによる実世界コンピューティング

階層型コンテンツビューア

Page 18: Web版Lindaによる実世界コンピューティング

階層型コンテンツビューア

ダイヤル パドル

ハードウェアとWebアプリの接続

Page 19: Web版Lindaによる実世界コンピューティング

BabaScript

結果

プログラム

人間を関数呼び出しできるDSL

Page 20: Web版Lindaによる実世界コンピューティング

多いので省略

Page 21: Web版Lindaによる実世界コンピューティング

Node-Lindaで

プログラミング

Page 23: Web版Lindaによる実世界コンピューティング

SFCのdelta棟から 流れているTupleが見える

http://linda-server.herokuapp.com/delta

Page 24: Web版Lindaによる実世界コンピューティング

ブラウザからTuple書き込める

ダミーデータ流せるので開発時に便利

Page 25: Web版Lindaによる実世界コンピューティング

接続クライアント (Node.js)var LindaClient = require('linda').Client;var socket = require(‘socket.io-client’).connect("http://localhost:8931");var linda = new LindaClient().connect(socket);

• socket.ioは接続切れても自動的に繋ぎ直したりしてくれて便利 • Node、ブラウザJS、Ruby、Android用などのクライアントライブラリがある

•最近Socket.IOを1.0.に上げたらiOS用が動かなくなった…

Page 26: Web版Lindaによる実世界コンピューティング

接続

クライアント (ブラウザJS)<script src="http://localhost:8931/socket.io/socket.io.js"></script><script src="http://localhost:8931/linda/linda.js"></script>

var socket = io.connect("http://localhost:8931");var linda = new Linda().connect(socket);

Page 27: Web版Lindaによる実世界コンピューティング

接続

クライアント (Ruby)require 'linda-socket.io-client'!linda = Linda::SocketIO::Client.connect 'http://localhost:8931'

Page 28: Web版Lindaによる実世界コンピューティング

接続

クライアント (Android Java)https://github.com/node-linda/linda-socket.io-client-java

Page 29: Web版Lindaによる実世界コンピューティング

Node-LindaのTuple操作

•write • read • take • watch • の4つだけ

Page 30: Web版Lindaによる実世界コンピューティング

writevar ts = linda.tuplespace("foo");ts.write({"type":"sensor", "name":"明るさ", "value": 1234});

{"type":"sensor", "name":"明るさ", "value": 1234}

{"type":"sensor", "name":"明るさ", "value": 1234}

書き込み

{"type":"sensor", "name":"明るさ", "value": 1400}

{"type":"sensor", "name":"温度", "value": 1400}

TupleSpace

Tuple

• Tuple = JSONシリアライズできるオブジェクト • 10分ぐらいで消える、expireプロパティで指定可能

Page 31: Web版Lindaによる実世界コンピューティング

readvar ts = linda.tuplespace("foo");ts.read({"type":"sensor", "name":"明るさ"}, function(err, tuple){ console.log(tuple.data); console.log(tuple.from);});

{"type":"sensor", "name":"明るさ", "value": 1234}

{"type":"sensor", "name":"明るさ", "value": 1400}

{"type":"sensor", "name":"温度", "value": 1400}

TupleSpace

オブジェクトの部分一致

• callbackなので、matchする物が無かったら現れるまで待つ •先にreadしておいて、後からwriteされても読める

{"type":"sensor", "name":"明るさ", "value": 1234}

{"type":"sensor", “name”:"明るさ"}に部分一致する物を1つ読み出し

Page 32: Web版Lindaによる実世界コンピューティング

take (削除しつつread)var ts = linda.tuplespace("foo");ts.take({"type":"sensor", "name":"明るさ"}, function(err, tuple){ console.log(tuple.data); console.log(tuple.from);});

{"type":"sensor", "name":"明るさ", "value": 1400}

{"type":"sensor", "name":"温度", "value": 1400}

TupleSpace

•読んだTupleは削除される{"type":"sensor", "name":"明るさ", "value": 1234}

{"type":"sensor", “name”:"明るさ"}で1つだけ読み出し

{"type":"sensor", "name":"

Page 33: Web版Lindaによる実世界コンピューティング

watch (監視)var ts = linda.tuplespace("foo");ts.watch({"type":"sensor", "name":"明るさ"}, function(err, tuple){ console.log(tuple.data); console.log(tuple.from);});

TupleSpace

• pub-sub が簡単に作れる{"type":"sensor", "name":"明るさ", "value": 1234}

{"type":"sensor", "name":"明るさ", "value": 1234}

writeした瞬間に

{"type":"sensor", “name”:"明るさ"}にマッチするTupleがすぐ出てくる

{ ~~~~ }{ ~~~~ } { ~~~~ }

Page 34: Web版Lindaによる実世界コンピューティング

cancelvar ts = linda.tuplespace("foo");var cid = ts.take({"type":"sensor", "name":"明るさ"}, function(err, tuple){ console.log(tuple.data);});!/** 2秒待って、take出来なかったらキャンセル **/setTimeout(function(){ ts.cancel(cid);}, 2000);

• read, take, watchを中止できる

•元祖Lindaのブロックしないread/takeは、Tupleが無ければnullが返るので、無ければ~~というコード書いたりする。しかしJavaScriptではブロックするコード書けない

• cancelで同等の事ができる

Page 35: Web版Lindaによる実世界コンピューティング

昨年実装したRuby版Lindaには「tupleが無ければすぐnullを返すread/take」があったのだが、cancelで同等の事ができるので機能削除した。

これによりクライアントライブラリの実装が小さくなり、Rubyは114行、jsは86行で済むようになった。クライアントライブラリ作りやすくする為に仕様を小さくするのは色々な言語で使えるために重要。

Page 36: Web版Lindaによる実世界コンピューティング

ドア開けるプログラム例ts = linda.tuplespace('delta')!linda.io.on 'connect', ->! ## watchで監視 ts.watch {type: 'door', cmd: 'open'}, (err, tuple) -> return if err or tuple.data.response? door_open_throttled -> res = tuple.data res.response = 'success' ts.write res ## 開けましたよ、とレスポンス!## ドア開ける関数door_open = (onComplete = ->) -> arduino.servoWrite 9, 0 # Arduinoのサーボ回す setTimeout -> arduino.servoWrite 9, 180 # サーボ戻す onComplete() , 2000!## ドア開ける関数をunderscoreで5秒にthrottleするdoor_open_throttled = _.throttle door_open, 5000, trailing: false

Page 37: Web版Lindaによる実世界コンピューティング

Tupleの例

Page 38: Web版Lindaによる実世界コンピューティング

温度センサーが毎秒流すTuple

{ "type": "sensor”, "name": "temperature", "value":25.6 }

Page 39: Web版Lindaによる実世界コンピューティング

人が来た

{ "type": "region", "action":"enter", "who": "shokai" }

Page 40: Web版Lindaによる実世界コンピューティング

人が去った

{ "type": "region", "action":"leave", "who": "shokai" }

Page 41: Web版Lindaによる実世界コンピューティング

ドア開けリクエスト

{ "type":"door", "cmd": "open", "who": "shokai" }

Page 42: Web版Lindaによる実世界コンピューティング

ドア開け成功

{ "type":"door", "cmd": "open", "who": "shokai", "response": "success" }

Page 43: Web版Lindaによる実世界コンピューティング

Tuple設計の知見•Tupleのプロパティに色々書いておくと柔軟になる。

•リクエストのTupleを原型とし、レスポンス値を追加したTupleを返すとわかりやすい

•物理的な部屋・場所毎にTupleSpaceを分けてみたが、全部屋の温度をwatchするプログラムが複雑になってしまった。”where”というプロパティを持たせれば良かったかも

Page 44: Web版Lindaによる実世界コンピューティング

• Tupleのプロパティに色々書いておくと柔軟になる。

•リクエストのTupleを原型とし、レスポンス値を追加したTupleを返すとわかりやすい

•物理的な部屋・場所毎にTupleSpaceを分けてみたが、全部屋の温度をwatchするプログラムが複雑になってしまった。”where”というプロパティを持たせれば良かったかも

Page 45: Web版Lindaによる実世界コンピューティング

Tupleのプロパティに色々書いておくと柔軟になる。

リクエストのTupleを原型とし、レスポンス値を追加したTupleを返すとわかりやすい

物理的な部屋・場所毎にTupleSpaceを分けてみたが、全部屋の温度をwatchするプログラムが複雑になってしまった。”where”というプロパティを持たせれば良かったかも

Page 46: Web版Lindaによる実世界コンピューティング

他の工夫 !

Webと接続したい 色んな言語・デバイスで接続したい 安定して動かして毎日使いたい 常に拡張しやすくしておきたい

Page 47: Web版Lindaによる実世界コンピューティング

安定して

動かしたい

Page 48: Web版Lindaによる実世界コンピューティング

全部Herokuで動かせば安定する

• linda-serverはすぐHerokuで動かせる !

•音を出す、モーターを回す等はその場にあるマシンで動かさないとならない

• Tupleをreadして(何か判断して)writeするようなのは、どこで動いていてもいいが、数がかなり多くなる

Page 49: Web版Lindaによる実世界コンピューティング

linda-worker• https://github.com/masuilab/linda-worker • Hubot風にLindaのスクリプトを1プロセスに詰め込んでHerokuで動かす

Page 50: Web版Lindaによる実世界コンピューティング

常に拡張しやすく

しておきたい

Page 51: Web版Lindaによる実世界コンピューティング

ことごとくTupleにして書き込めば 拡張性高くなる

•明るさセンサのTuple • 電気ついた・消えたTuple • 人がいるらしいぞTuple • sayしろ/Yoしろ/チャットに通知しろTuple • など全てTupleにして書き込むと、途中のどこからでも拡張可能

•速度は十分出るので、アメリカと毎回通信しているとか考えない

Page 52: Web版Lindaによる実世界コンピューティング

よくある質問

Page 53: Web版Lindaによる実世界コンピューティング

認証

•変なTuple書き込まれたくないんだけど? !

• Socket.IOの認証でどうにかしたい、調査中 • tuple.fromでリモートホスト見れるよ

Page 54: Web版Lindaによる実世界コンピューティング

マイコンとNode等はどう接続してるの?

•各言語の中にArduinoコードが書けるライブラリ作った • https://npmjs.org/package/arduino-firmata • https://npmjs.org/package/ble-firmata • http://rubygems.org/gems/arduino_firmata • http://shokai.github.io/ArduinoFirmata-Android/

Page 55: Web版Lindaによる実世界コンピューティング

Tupleはどこに保存されているの?

•Nodeプロセスのオンメモリに保存されてます •溢れないようにexpireを3分毎にチェックしている •永続化はしない方針 • 4ヶ月ぐらい動かし続けても安定しているので(研究室程度の規模なら)大丈夫だと思う

Page 56: Web版Lindaによる実世界コンピューティング

複数のTupleがマッチする場合、どれが取れるの?

•一番新しいTuple、つまり最後に書き込まれたTupleが取れます

•古いTupleを取りたい場合、何回もtakeしていくしかない

• Tupleを全てtakeするには34ページのcancelとsetTimeoutを使ってください

Page 57: Web版Lindaによる実世界コンピューティング

take/read/watchの順番•先にtake/read/watchのリクエストが来ていて、その後writeされた場合

• readとtakeとwatchを、先着順に評価する • Tupleがtakeで削除された場合、それ以降のreadとwatchには配信されない

•質疑応答の時に、まずwatchにmatchするクライアント全員に配信されると言いましたが勘違いでした!!

Page 58: Web版Lindaによる実世界コンピューティング

悪い人がtakeしたら?

•takeされたら、そのTupleは消えます • read/watch/takeは先着順に評価されるので、watchしておけばtakeされてもwriteを全部取れる

• takeできないtupleを作る、とか権限とか考えたけど、シンプルさが無くなるのでやめました

•ルールを守って楽しいLinda

Page 59: Web版Lindaによる実世界コンピューティング

ぶっちゃけwatchしか使わないのでは?

•センサーデータを流して色々デバイスを動かすような場合は、writeとwatchしか使いませんでした

•こういう最新のデータを返すような場合にreadが便利 !

!

!

• takeはタスク分散以外であまり使わないかも

Page 60: Web版Lindaによる実世界コンピューティング

MongoDBとの違い•書き込まれたTupleをすぐ配信できる(watchでpub-subできる)

• 1プロセスにたくさん接続できる •ブラウザJSが直接接続できる •実はNodeアプリにライブラリとして読み込めて、既存のSocket.IO接続と共存できるのでちょっとしたツールを作るのにも便利

Page 61: Web版Lindaによる実世界コンピューティング

MQTTとの違い•MQTTでもいいのではないかと思う •MQTTはコネクションしっかり貼らないセンサネットワーク等でも使えるようになっているが、lindaはSocket.IO前提

•しかしIBMのMQTT broakerはwebsocketでも接続できるので、ブラウザJSからも使えるようです

•もっと調査します •MQTTぱっと見た感じ、pub側に権力が集中しすぎに見える。QoSもデータ量もpub側次第になるけど、subにどんなアプリケーションが来るかわかっていない状況で「とりあえずデータ流しておこう」という用途には難しそう。ガジェットが増える毎に自宅の仕様は変わる。設計が常にベータ版な環境で建て増しを続けられるのか?

Page 62: Web版Lindaによる実世界コンピューティング

Herokuのステマ?•はい • Herokuは最高 • Herokuで動かしやすいように作っておくと、どこでも動かせる感じがして好き

• linda-workerとlinda-serverが互いに通信しあってherokuプロセスが寝ないようになっている

Page 63: Web版Lindaによる実世界コンピューティング

まとめ

Page 64: Web版Lindaによる実世界コンピューティング

まとめ

•色々な言語から使えるLinda実装を作った •センサー読んですぐアクチュエータ動かさずに、細かくTupleにして連鎖させると拡張しやすい

•なるべくHeroku等で動かすと安定する

Page 65: Web版Lindaによる実世界コンピューティング

おわり