dRuby, Again. · Rails様様 ERB利用者急増中 ... 二つのirbを使って話し合う ......

Post on 13-Oct-2020

0 views 0 download

Transcript of dRuby, Again. · Rails様様 ERB利用者急増中 ... 二つのirbを使って話し合う ......

dRuby, Again.

dRubyをもう一度思い出してみよう今日も古い話ばっかり

重要なことを先に

先に

重要

昨夏リリースまだ初版買えます!

dRubyによる

関 将俊 著

分散・Webプログラミング

私について

咳今日はAgileの人じゃないよ

内向的なプログラマコードにつぶやく

作ったもの

ERBdRubyRWiki

作ったものの‥

Div, Tofudivip - ユーザ数1

proxyネタPRb, KoyaARb

ERBについて

eRubyの実装の一つRubyを文書に埋め込む - 普通それをRubyに埋め込む - ふつうフレームワーク作る人むけ?

詳しくはこちら

網道編

Rails様様

ERB利用者急増中

dRuby

Ruby限定の分散オブジェクトRMIRubyの特徴をそのままにIDL不要ブロック付きメソッド

dRuby再入門の前に

忘れていた歴史についててゆか昨日から歴史ばっかり

’98 shttpsrv

はじめにshttpsrvがあった原信一郎さんのhttpd

servlet拡張erb拡張

当時の素振り

やっぱりbookmarkタグ付けするやつ

RDBをshttpsrvで隠すUIのshttpsrvとhttpで繋ぐ

こんなの

shttpsrv+servlet

PostgreSQL

shttpsrv+servlet

plain text

shttpsrv+servlet

HTTP

HTTP

HTTPUI担当

データベース

user管理

RMI over HTTP

発見

みんなserverでclientだhttpをRubyっぽくラップめんどくさい

じゃdRuby作ろう

shttpsrvの実装をマネる要求ごとのThread

かっこいいRubyのライブラリTCPSocketMarshal

できた

200行くらいRubyすごい

dRubyのやること

Rubyのメッセージングを拡張別のプロセスのオブジェクトのメソッドを起動する

メッセージング

オブジェクトにメッセージを送信メソッドを起動ちょっと嘘かも

Object(1) メッセージ送信

(2) メソッド起動

Object(1) メッセージ送信

Object(2) メッセージ転送

(3) メソッド起動

プロセスを越える

実験

二つのirbを使って話し合う一方はHashを公開

front

システムへの入り口、きっかけURIで指定するdRubyのシステムに一つ以上

irb

cinq:~ mas$ irb --simple-prompt --noreadline>> require 'drb/drb'=> true>>

cinq:~ mas$ irb --simple-prompt --noreadline>> require 'drb/drb'=> true>>

OSXでThreadがスイッチしない

{}をfrontに

>> DRb.start_service('druby://localhost:12345', {})=> #<DRb::DRbServer:0x1c1e48....>>>

{}とURIを結びつける

frontを参照

>> DRb.start_service=> #<DRb::DRbServer:0x1c97c4...>>> ro = DRbObject.new_with_uri('druby://localhost:12345')=> #<DRb::DRbObject:....>>>

URIを参照する

{}をいじる>> ro['client'] = 'Hello, Again'=> "Hello, Again">>

>> DRb.front=> {"client"=>"Hello, Again"}>> DRb.front['server'] = 'Hello, World.'=> "Hello, World.">>

>> ro['server']=> "Hello, World.">> ro=> #<DRb::DRbObject:...">>> ro.keys=> ["client", "server"]>> ro.values => ["Hello, Again", "Hello, World."]>>

オブジェクトの交換

Marshal

dumpablepass by value

Number, String, Boolean...

can’t dumppass by reference

Proc, Thread, File ...

Threadは参照渡し

>> DRb.front['thread'] = Thread.current=> #<Thread:0x1df7cc run>>>

>> ro['thread']=> #<DRb::DRbObject:...>>> ro['thread'].status=> "sleep">>

値渡しはコピー

>> DRb.front['client']=> "Hello, Again">>

>> ro['client']=> "Hello, Again">> ro['client'].reverse! => "niagA ,olleH">> ro['client']=> "Hello, Again">>

ブロック付きメソッド

なぜ動くのかProcは参照渡しyieldはProcへの操作

リモートなeach

>> ro.each {|k, v| p [k, v]}["thread", #<DRb::DRbObject:...>]["client", "Hello, Again"]["server", "Hello, World."]=> #<DRb::DRbObject:...">>> ro.find_all {|k, v| String === v}=> [["client", "Hello, Again"], ["server", "Hello, World."]]>>

Rubyなので

IDL不要proxyは一種類だけ

class Counter>> class Counter>> include MonitorMixin>> include DRbUndumped>> def initialize >> super()>> @value = 0>> end>> def up>> synchronize do?> @value += 1>> end>> end>> attr_reader :value>> end=> nil>> DRb.front['counter'] = Counter.new=> #<Counter:...>>>

Counter知りません

>> ro['counter'].up=> 1>> ro['counter'].up=> 2>> ro['counter'].up=> 3>> ro['counter'].value=> 3>>

同期

Thread同期の仕組みもそのまま

SizedQueue>> require 'thread' => false>> DRb.front['queue'] = SizedQueue.new(1)=> #<SizedQueue:...>>> DRb.front['queue'].push(1)=> nil>> DRb.front['queue'].push(2)

>> rq = DRbObject.new_with_uri('druby://localhost:12345?queue')=> #<DRb::DRbObject:...>>> rq.pop=> 1>> rq.pop=> 2>> rq.pop

=> nil>> DRb.front['queue'].push(3)=> #<Thread:...>>>

=> 3>>

OptionつきURI

で?

dRubyをなにに使うの?

いろんな分散

配置プロセスマシン

機能ちょっと豪華な通信の代替手段

配置と寿命

オブジェクトはプロセスに在る住いが異なる = 寿命が異なるプロセスより長命なオブジェクト

寿命といえば永続化

永遠の永続化比較的に永続化一方よりは長生きだ

OODB?

オブジェクトをそのまましまうしまうというよりそこに在る

RWiki

オンメモリOODBオブジェクトをサーバに配置再起動の際の手がかりをログRD形式

生きてるRWiki

RDHTTP dRuby

dRuby Log

RWiki

daemon

CGI

interface

Application

起動時のRWiki

ログから再構築運用中は書き込むだけ

RD

Log

RWiki

daemon

RWiki Prop

RD Data - 構想があったyaml風味

RD PropRDの木からオブジェクトをStoryCard拡張

StoryCard拡張

ストーリーをオブジェクトに10000件たぶんスケールしない

統計情報、テストケース、サマリさまざまなログ

長命なオブジェクト

長生きするオブジェクトの方が自然なときWeb UIとか

event driven

GUIWeb UIコンテキストが細切れ

通信周り

Web UI

Webブラウザ HTTP 遺言系CGI 遺言

Event !だいぶ短命長生き

遺言にcontextを

遺言作戦

プロセスの寿命を超えるためにさまざまな状態を遺すだんだん饒舌に

遺言はどこに

URLくっきぃファイルRDBMS

相続問題

排他制御運用回避

遺言に苦労するなら

はじめから長命なオブジェクトはいかが?つーかそのMVCでいいの?

Web UI 2.0

Webブラウザ HTTP Web UI アプリケーション

Event !だいぶ短命

長生きだと自然

長生き

Web UIへの応用例

Div::Div / TofuWeb Applicationのフレームワークじゃないらしい

もっとかっこいいやつ

並列処理糊言語 LindaとRinda動的な構成変更 Ring使わなくても素振りしておけ

Linda

並列処理糊言語タプルとタプルスペースパターンマッチング

Lindaの協調

outinとrdパターンで指定ブロックできる

参加者はタプルスペースだけを知ってる

かっこいい並列処理

TupleSpace

Engine

Engine

Engine

Client

Client

Tuple Spaceだけを知っている

Rinda

RubyによるLindaの実装dRubyを意識してくれるTupleはArray|Hashで

TupleSpace

>> ts = Rinda::TupleSpace.new=> #<Rinda::TupleSpace:...>>> DRb.front['ts'] = ts=> #<Rinda::TupleSpace:...>>>

>> it = DRbObject.new_with_uri('druby://localhost:12345?ts')=> #<DRb::DRbObject:...>>> ts = Rinda::TupleSpaceProxy.new(it)=> #<Rinda::TupleSpaceProxy:...>>>

TupleSpaceProxyはdRuby下で安全に動作させるためのもの

writeとtake

>> ts.write([:seki, :age, 20])=> #<Rinda::TupleEntry:...>>> TupleSpace

:seki :age

write

20

writeとtake

>> ts.write([:seki, :age, 20])=> #<Rinda::TupleEntry:...>>>

>> ts.take([:seki, :age, nil]) => [:seki, :age, 20]>>

TupleSpace

:seki :age

take

20

待ち合わせ

>> ts.take([:seki, :age, nil])

TupleSpace

take

待ち合わせ

>> ts.write([:seki, :age, 20])=> #<Rinda::TupleEntry:...>>>

>> ts.take([:seki, :age, nil])

TupleSpace

:seki :age

writetake

20

待ち合わせ

>> ts.write([:seki, :age, 20])=> #<Rinda::TupleEntry:...>>>

=> [:seki, :age, 20]>>

>> ts.take([:seki, :age, nil])

TupleSpace

:seki :age

take

20

安全なカウンタ

値のタプルを資源と考える同時にただ一つのプロセスだけが値を更新できる

安全なカウンタ>> tuple = ts.take([:count, nil])

TupleSpace

take

安全なカウンタ

>> ts.write([:count, 0])=> #<Rinda::TupleEntry:...>>>

>> tuple = ts.take([:count, nil])

TupleSpace

:count 0

takewrite

安全なカウンタ

>> ts.write([:count, 0])=> #<Rinda::TupleEntry:...>>>

=> [:count, 0]>>

>> tuple = ts.take([:count, nil])

TupleSpace

take

:count 0

安全なカウンタ

>> ts.write([:count, 0])=> #<Rinda::TupleEntry:...>>>

=> [:count, 0]>>

>> tuple = ts.take([:count, nil])

>> tuple = ts.take([:count, nil])

>> tuple[1] += 1=> 1>> ts.write(tuple)=> #<DRb::DRbObject:...>>>

TupleSpace

:count 1

writetake

=> [:count, 1]>>

frontとURI, Again

dRubyでは少なくとも1つのURIを知らなくてはならない名前サーバを用意しても結局‥

Ring

名前サーバすら知らずに動きたいTupleSpaceを探す仕組みそこに名前を登録する決めごと有効期限付きTuple

RingFinger

近くのTupleSpaceを探し出すUDPでブロードキャスト

Ringの参加者は

TupleSpaceをlookup自サービスを登録必要なサービスを取得

参加者がこけた

有効期限をすぎたTupleは削除完全ではないがまあまあ動く

実験

割愛druby.orgのCMS

druby.orgのための

動的にWEBrickにmountサービスの追加簡単

起動順序を気にしない再起動も

TupleSpace

WEBrick RWiki

Formatter

Div

未来を少しだけ語る

proxyネタKoyaARb

重要な点をもう一度

昨夏リリースまだ初版買えます!

dRubyによる

関 将俊 著

分散・Webプログラミング