1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

import drb/sample

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5698 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
seki 2004-02-14 02:28:02 +00:00
parent 0562a84558
commit 30ff0b6aeb
44 changed files with 1966 additions and 0 deletions

56
sample/drb/README.rd Normal file
View file

@ -0,0 +1,56 @@
= Sample scripts
* array and iteretor
* darray.rb --- server
* darrayc.rb --- client
* simple chat
* dchats.rb --- server
* dchatc.rb --- client
* distributed chasen (for Japanese)
* dhasen.rb --- server
* dhasenc.rb --- client
* simple log server
* dlogd.rb --- server
* dlogc.rb --- client
* Queue server, and DRbUnknown demo
* dqueue.rb --- server
* dqin.rb --- client. push DQEntry objects.
* dqout.rb --- client. pop DQEntry objects.
* dqlib.rb --- define DQEntry
* IdConv customize demo: reference by name
* name.rb --- server
* namec.rb --- client
* extserv
* extserv_test.rb
* IdConv customize demo 2: using TimerIdConv
* holders.rb --- server
* holderc.rb --- client
* rinda, remote tuplespace
* rinda_ts.rb --- TupleSpace server.
* rindas.rb --- provide simple service via TupleSpace.
* rindac.rb --- service user
* observer
cdbiff - ((<URI:http://namazu.org/~satoru/cdbiff/>))
* dbiff.rb --- dcdbiff server
* dcdbiff.rb --- dcdbiff client
* drbssl
* drbssl_s.rb
* drbssl_c.rb
* add DRbProtocl
* http0.rb
* http0serv.rb
* Rinda::Ring
* ring_place.rb
* ring_echo.rb

59
sample/drb/README.rd.ja Normal file
View file

@ -0,0 +1,59 @@
= サンプルスクリプト
* Arrayをリモートから利用してイテレータを試す。
* darray.rb --- server
* darrayc.rb --- client
* 簡易チャット
* dchats.rb --- server
* dchatc.rb --- client
* 分散chasen
* dhasen.rb --- server
* dhasenc.rb --- client
* 簡易ログサーバ
* dlogd.rb --- server
* dlogc.rb --- client
* Queueサーバ。
クライアントdqin.rbはQueueサーバの知らないオブジェクト(DQEntry)を
pushするがDRbUnknownによりクライアントdqout.rbがpopできる。
* dqueue.rb --- server
* dqin.rb --- client。DQEntryオブジェクトをpushする
* dqout.rb --- client。DQEntryオブジェクトをpopする
* dqlib.rb --- DQEntryを定義したライブラリ
* 名前による参照
IdConvをカスタマイズしてidでなく名前で参照する例
* name.rb --- server
* namec.rb --- client
* extservのサンプル
* extserv_test.rb
* TimerIdConvの使用例
* holders.rb --- server。ruby -d hodlers.rbとするとTimerIdConvを使用する。
* holderc.rb --- client
* rinda.rbの使用例
* rinda_ts.rb --- TupleSpaceサーバ。
* rindac.rb --- TupleSpaceのclientでアプリケーションのclient
* rindas.rb --- TupleSpaceのclientでアプリケーションのserver
* observerの使用例
cdbiff - ((<URI:http://namazu.org/~satoru/cdbiff/>))
* dbiff.rb --- dcdbiff server
* dcdbiff.rb --- dcdbiff client
* drbsslの使用例
* drbssl_s.rb
* drbssl_c.rb
* DRbProtoclの追加例
* http0.rb
* http0serv.rb
* ringの使用例
* ring_place.rb
* ring_echo.rb

13
sample/drb/darray.rb Normal file
View file

@ -0,0 +1,13 @@
=begin
distributed Ruby --- Array
Copyright (c) 1999-2001 Masatoshi SEKI
=end
require 'drb/drb'
here = ARGV.shift
DRb.start_service(here, [1, 2, "III", 4, "five", 6])
puts DRb.uri
puts '[return] to exit'
gets

59
sample/drb/darrayc.rb Normal file
View file

@ -0,0 +1,59 @@
=begin
distributed Ruby --- Array client
Copyright (c) 1999-2001 Masatoshi SEKI
=end
require 'drb/drb'
there = ARGV.shift || raise("usage: #{$0} <server_uri>")
DRb.start_service(nil, nil)
ro = DRbObject.new(nil, there)
p ro.size
puts "# collect"
a = ro.collect { |x|
x + x
}
p a
puts "# find"
p ro.find { |x| x.kind_of? String }
puts "# each, break"
ro.each do |x|
next if x == "five"
puts x
end
puts "# each, break"
ro.each do |x|
break if x == "five"
puts x
end
puts "# each, next"
ro.each do |x|
next if x == "five"
puts x
end
puts "# each, redo"
count = 0
ro.each do |x|
count += 1
puts count
redo if count == 3
end
puts "# each, retry"
retried = false
ro.each do |x|
puts x
if x == 4 && !retried
puts 'retry'
retried = true
retry
end
end

51
sample/drb/dbiff.rb Normal file
View file

@ -0,0 +1,51 @@
#
# dbiff.rb - distributed cdbiff (server)
# * original: cdbiff by Satoru Takabayashi <http://namazu.org/~satoru/cdbiff>
require 'drb/drb'
require 'drb/eq'
require 'drb/observer'
class Biff
include DRb::DRbObservable
def initialize(filename, interval)
super()
@filename = filename
@interval = interval
end
def run
last = Time.now
while true
begin
sleep(@interval)
current = File::mtime(@filename)
if current > last
changed
begin
notify_observers(@filename, current)
rescue Error
end
last = current
end
rescue
next
end
end
end
end
def main
filename = "/var/mail/#{ENV['USER']}"
interval = 15
uri = 'druby://:19903'
biff = Biff.new(filename, interval)
DRb.start_service(uri, biff)
biff.run
end
main

43
sample/drb/dcdbiff.rb Normal file
View file

@ -0,0 +1,43 @@
#
# dcdbiff.rb - distributed cdbiff (client)
# * original: cdbiff by Satoru Takabayashi <http://namazu.org/~satoru/cdbiff>
require 'drb/drb'
require 'drb/eq'
class Notify
include DRbUndumped
def initialize(biff, command)
@biff = biff
@command = command
@biff.add_observer(self)
end
def update(filename, time)
p [filename, time] if $DEBUG
system(@command)
end
def done
begin
@biff.delete_observer(self)
rescue
end
end
end
def main
command = 'eject'
uri = 'druby://localhost:19903'
DRb.start_service
biff = DRbObject.new(nil, uri)
notify = Notify.new(biff, command)
trap("INT"){ notify.done }
DRb.thread.join
end
main

41
sample/drb/dchatc.rb Normal file
View file

@ -0,0 +1,41 @@
=begin
distributed Ruby --- chat client
Copyright (c) 1999-2000 Masatoshi SEKI
=end
require 'drb/drb'
class ChatClient
include DRbUndumped
def initialize(name)
@name = name
@key = nil
end
attr_reader(:name)
attr_accessor(:key)
def message(there, str)
raise 'invalid key' unless @key == there
puts str
end
end
if __FILE__ == $0
begin
there = ARGV.shift
name = ARGV.shift
raise "usage" unless (there and name)
rescue
$stderr.puts("usage: #{$0} <server_uri> <your_name>")
exit 1
end
DRb.start_service
ro = DRbObject.new(nil, there)
chat = ChatClient.new(name)
entry = ro.add_member(chat)
while gets
entry.say($_)
end
end

71
sample/drb/dchats.rb Normal file
View file

@ -0,0 +1,71 @@
=begin
distributed Ruby --- chat server
Copyright (c) 1999-2000 Masatoshi SEKI
=end
require 'thread'
require 'drb/drb'
class ChatEntry
include DRbUndumped
def initialize(server, there)
@server = server
@there = there
@name = there.name
@key = there.key = Time.now
end
attr :name, true
attr :there
def say(str)
@server.distribute(@there, str)
end
def listen(str)
@there.message(@key, str)
end
end
class ChatServer
def initialize
@mutex = Mutex.new
@members = {}
end
def add_member(there)
client = ChatEntry.new(self, there)
@mutex.synchronize do
@members[there] = client
end
client
end
def distribute(there, str)
name = @members[there].name
msg = "<#{name}> #{str}"
msg2 = ">#{name}< #{str}"
@mutex.synchronize do
for m in @members.keys
begin
if m == there
@members[m].listen(msg2)
else
@members[m].listen(msg)
end
rescue
p $!
@members.delete(m)
end
end
end
end
end
if __FILE__ == $0
here = ARGV.shift
DRb.start_service(here, ChatServer.new)
puts DRb.uri
puts '[return] to exit.'
gets
end

43
sample/drb/dhasen.rb Normal file
View file

@ -0,0 +1,43 @@
=begin
distributed Ruby --- dRuby Sample Server --- chasen server
Copyright (c) 1999-2001 Masatoshi SEKI
=end
=begin
How to play.
Terminal 1
| % ruby dhasen.rb
| druby://yourhost:7640
Terminal 2
| % ruby dhasenc.rb druby://yourhost:7640
=end
require 'drb/drb'
require 'chasen'
require 'thread'
class Dhasen
include DRbUndumped
def initialize
@mutex = Mutex.new
end
def sparse(str, *arg)
@mutex.synchronize do
Chasen.getopt(*arg)
Chasen.sparse(str)
end
end
end
if __FILE__ == $0
DRb.start_service(nil, Dhasen.new)
puts DRb.uri
puts '[return] to exit.'
gets
end

13
sample/drb/dhasenc.rb Normal file
View file

@ -0,0 +1,13 @@
=begin
distributed Ruby --- dRuby Sample Client -- chasen client
Copyright (c) 1999-2001 Masatoshi SEKI
=end
require 'drb/drb'
there = ARGV.shift || raise("usage: #{$0} <server_uri>")
DRb.start_service
dhasen = DRbObject.new(nil, there)
print dhasen.sparse("塑泣は、啦欧なり。", "-F", '(%BB %m %M)\n', "-j")
print dhasen.sparse("塑泣は、啦欧なり。", "-F", '(%m %M)\n')

16
sample/drb/dlogc.rb Normal file
View file

@ -0,0 +1,16 @@
=begin
distributed Ruby --- Log test
Copyright (c) 1999-2001 Masatoshi SEKI
=end
require 'drb/drb'
there = ARGV.shift || raise("usage: #{$0} <server_uri>")
DRb.start_service
ro = DRbObject.new(nil, there)
ro.log(123)
ro.log("hello")
sleep 2
ro.log("wakeup")

39
sample/drb/dlogd.rb Normal file
View file

@ -0,0 +1,39 @@
=begin
distributed Ruby --- Log server
Copyright (c) 1999-2000 Masatoshi SEKI
=end
require 'drb/drb'
require 'thread'
class Logger
def initialize(fname)
@fname = fname.to_s
@fp = File.open(@fname, "a+")
@queue = Queue.new
@th = Thread.new { self.flush }
end
def log(str)
@queue.push("#{Time.now}\t" + str.to_s)
end
def flush
begin
while(1)
@fp.puts(@queue.pop)
@fp.flush
end
ensure
@fp.close
end
end
end
if __FILE__ == $0
here = ARGV.shift
DRb.start_service(here, Logger.new('/usr/tmp/dlogd.log'))
puts DRb.uri
DRb.thread.join
end

13
sample/drb/dqin.rb Normal file
View file

@ -0,0 +1,13 @@
=begin
distributed Ruby --- store
Copyright (c) 1999-2000 Masatoshi SEKI
=end
require 'drb/drb'
require 'dqlib'
there = ARGV.shift || raise("usage: #{$0} <server_uri>")
DRb.start_service
queue = DRbObject.new(nil, there)
queue.push(DQEntry.new(DRb.uri))

14
sample/drb/dqlib.rb Normal file
View file

@ -0,0 +1,14 @@
class DQEntry
def initialize(name)
@name = name
end
def greeting
"Hello, This is #{@name}."
end
alias to_s greeting
end
if __FILE__ == $0
puts DQEntry.new('DQEntry')
end

14
sample/drb/dqout.rb Normal file
View file

@ -0,0 +1,14 @@
=begin
distributed Ruby --- fetch
Copyright (c) 1999-2000 Masatoshi SEKI
=end
require 'drb/drb'
require 'dqlib'
there = ARGV.shift || raise("usage: #{$0} <server_uri>")
DRb.start_service
queue = DRbObject.new(nil, there)
entry = queue.pop
puts entry.greeting

13
sample/drb/dqueue.rb Normal file
View file

@ -0,0 +1,13 @@
=begin
distributed Ruby --- Queue
Copyright (c) 1999-2000 Masatoshi SEKI
=end
require 'thread'
require 'drb/drb'
DRb.start_service(nil, Queue.new)
puts DRb.uri
puts '[return] to exit'
gets

45
sample/drb/drbc.rb Normal file
View file

@ -0,0 +1,45 @@
=begin
distributed Ruby --- dRuby Sample Client
Copyright (c) 1999-2000 Masatoshi SEKI
=end
require 'drb/drb'
class DRbEx2
include DRbUndumped
def initialize(n)
@n = n
end
def to_i
@n.to_i
end
end
if __FILE__ == $0
there = ARGV.shift
unless there
$stderr.puts("usage: #{$0} <server_uri>")
exit 1
end
DRb.start_service()
ro = DRbObject.new_with_uri(there)
puts ro
p ro.to_a
puts ro.hello
p ro.hello
puts ro.sample(DRbEx2.new(1), 2, 3)
puts ro.sample(1, ro.sample(DRbEx2.new(1), 2, 3), DRbEx2.new(3))
begin
ro.err
rescue DRb::DRbUnknownError
p $!
p $!.unknown
rescue RuntimeError
p $!
end
end

48
sample/drb/drbch.rb Normal file
View file

@ -0,0 +1,48 @@
=begin
distributed Ruby --- dRuby Sample Client
Copyright (c) 1999-2000 Masatoshi SEKI
=end
require 'drb/drb'
require 'drb/http'
class DRbEx2
include DRbUndumped
def initialize(n)
@n = n
end
def to_i
@n.to_i
end
end
if __FILE__ == $0
there = ARGV.shift
unless there
$stderr.puts("usage: #{$0} <server_uri>")
exit 1
end
DRb::DRbConn.proxy_map['x68k'] = 'http://x68k/~mas/http_cgi.rb'
DRb.start_service()
ro = DRbObject.new(nil, there)
puts ro
p ro.to_a
puts ro.hello
p ro.hello
puts ro.sample(DRbEx2.new(1), 2, 3)
puts ro.sample(1, ro.sample(DRbEx2.new(1), 2, 3), DRbEx2.new(3))
begin
ro.err
rescue DRb::DRbUnknownError
p $!
p $!.unknown
rescue RuntimeError
p $!
end
end

59
sample/drb/drbm.rb Normal file
View file

@ -0,0 +1,59 @@
=begin
multiple DRbServer
Copyright (c) 1999-2002 Masatoshi SEKI
=end
=begin
How to play.
Terminal 1
| % ruby drbm.rb
| druby://yourhost:7640 druby://yourhost:7641
Terminal 2
| % ruby drbmc.rb druby://yourhost:7640 druby://yourhost:7641
| [#<DRb::DRbObject .... @uri="druby://yourhost:7640">, "FOO"]
| [#<DRb::DRbObject .... @uri="druby://yourhost:7641">, "FOO"]
=end
require 'drb/drb'
class Hoge
include DRbUndumped
def initialize(s)
@str = s
end
def to_s
@str
end
end
class Foo
def initialize(s='FOO')
@hoge = Hoge.new(s)
end
def hello
@hoge
end
end
class Bar < Foo
def initialize(foo)
@hoge = foo.hello
end
end
if __FILE__ == $0
foo = Foo.new
s1 = DRb::DRbServer.new('druby://:7640', foo)
s2 = DRb::DRbServer.new('druby://:7641', Bar.new(foo))
puts "#{s1.uri} #{s2.uri}"
gets
end

22
sample/drb/drbmc.rb Normal file
View file

@ -0,0 +1,22 @@
=begin
multiple DRbServer client
Copyright (c) 1999-2002 Masatoshi SEKI
=end
require 'drb/drb'
if __FILE__ == $0
s1 = ARGV.shift
s2 = ARGV.shift
unless s1 && s2
$stderr.puts("usage: #{$0} <server_uri1> <server_uri2>")
exit 1
end
DRb.start_service()
r1 = DRbObject.new(nil, s1)
r2 = DRbObject.new(nil, s2)
p [r1.hello, r1.hello.to_s]
p [r2.hello, r2.hello.to_s]
end

51
sample/drb/drbs-acl.rb Normal file
View file

@ -0,0 +1,51 @@
=begin
distributed Ruby --- dRuby Sample Server
Copyright (c) 1999-2000 Masatoshi SEKI
=end
=begin
How to play.
Terminal 1
| % ruby drbs.rb
| druby://yourhost:7640
Terminal 2
| % ruby drbc.rb druby://yourhost:7640
| "hello"
| 6
| 10
=end
require 'drb/drb'
require 'acl'
class DRbEx
def initialize
@hello = 'hello'
end
def hello
info = Thread.current['DRb']
p info['socket'].peeraddr if info
@hello
end
def sample(a, b, c)
a.to_i + b.to_i + c.to_i
end
end
if __FILE__ == $0
acl = ACL.new(%w(deny all
allow 192.168.1.*
allow localhost))
DRb.install_acl(acl)
DRb.start_service(nil, DRbEx.new)
puts DRb.uri
DRb.thread.join
end

64
sample/drb/drbs.rb Normal file
View file

@ -0,0 +1,64 @@
=begin
distributed Ruby --- dRuby Sample Server
Copyright (c) 1999-2000,2002 Masatoshi SEKI
=end
=begin
How to play.
Terminal 1
| % ruby drbs.rb
| druby://yourhost:7640
Terminal 2
| % ruby drbc.rb druby://yourhost:7640
| "hello"
| ....
=end
require 'drb/drb'
class DRbEx
include DRbUndumped
def initialize
@hello = 'hello'
end
def hello
cntxt = Thread.current['DRb']
if cntxt
p cntxt['server'].uri
p cntxt['client'].peeraddr
end
Foo::Unknown.new
end
def err
raise FooError
end
def sample(a, b, c)
a.to_i + b.to_i + c.to_i
end
end
class Foo
class Unknown
end
end
class FooError < RuntimeError
end
if __FILE__ == $0
DRb.start_service(ARGV.shift || 'druby://:7640', DRbEx.new)
puts DRb.uri
Thread.new do
sleep 10
DRb.stop_service
end
DRb.thread.join
end

19
sample/drb/drbssl_c.rb Normal file
View file

@ -0,0 +1,19 @@
#!/usr/bin/env ruby
require 'drb'
require 'drb/ssl'
there = ARGV.shift || "drbssl://localhost:3456"
config = Hash.new
config[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
config[:SSLVerifyCallback] = lambda{|ok,x509_store|
p [ok, x509_store.error_string]
true
}
DRb.start_service(nil,nil,config)
h = DRbObject.new(nil, there)
while line = gets
p h.hello(line.chomp)
end

32
sample/drb/drbssl_s.rb Normal file
View file

@ -0,0 +1,32 @@
#!/usr/bin/env ruby
require 'drb'
require 'drb/ssl'
here = ARGV.shift || "drbssl://localhost:3456"
class HelloWorld
include DRbUndumped
def hello(name)
"Hello, #{name}."
end
end
config = Hash.new
config[:verbose] = true
begin
data = open("sample.key"){|io| io.read }
config[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(data)
data = open("sample.crt"){|io| io.read }
config[:SSLCertificate] = OpenSSL::X509::Certificate.new(data)
rescue
$stderr.puts "Switching to use self-signed certificate"
config[:SSLCertName] =
[ ["C","JP"], ["O","Foo.DRuby.Org"], ["CN", "Sample"] ]
end
DRb.start_service(here, HelloWorld.new, config)
puts DRb.uri
$stdin.gets
DRb.stop_service

View file

@ -0,0 +1,80 @@
=begin
dRuby sample
Copyright (c) 2000 Masatoshi SEKI
= How to play
* Terminal 1
% ruby -I. extserv_test.rb server
druby://yourhost:12345
* Terminal 2
% ruby -I. extserv_test.rb druby://yourhost:12345
...
=end
require 'drb/drb'
def ARGV.shift
it = super()
raise "usage:\nserver: #{$0} server [<uri>]\nclient: #{$0} [quit] <uri>" unless it
it
end
class Foo
include DRbUndumped
def initialize(str)
@str = str
end
def hello(it)
"#{it}: #{self}"
end
def to_s
@str
end
end
cmd = ARGV.shift
case cmd
when 'itest1', 'itest2'
require 'drb/extserv'
front = Foo.new(cmd)
server = DRb::DRbServer.new(nil, front)
es = DRb::ExtServ.new(ARGV.shift, ARGV.shift, server)
server.thread.join
when 'server'
require 'drb/extservm'
DRb::ExtServManager.command['itest1'] = "ruby -I. #{$0} itest1"
DRb::ExtServManager.command['itest2'] = "ruby -I. #{$0} itest2"
s = DRb::ExtServManager.new
DRb.start_service(ARGV.shift, s)
puts DRb.uri
DRb.thread.join
else
uri = (cmd == 'quit') ? ARGV.shift : cmd
DRb.start_service
s = DRbObject.new(nil, uri)
t1 = s.service('itest1').front
puts t1
t2 = s.service('itest2').front
puts t2
puts t1.hello(t2)
if (cmd == 'quit')
s.service('itest1').stop_service
s.service('itest2').stop_service
end
end

29
sample/drb/gw_ct.rb Normal file
View file

@ -0,0 +1,29 @@
require 'drb/drb'
class Foo
include DRbUndumped
def foo(n)
n + n
end
def bar(n)
yield(n) + yield(n)
end
end
DRb.start_service(nil)
puts DRb.uri
ro = DRbObject.new(nil, ARGV.shift)
ro[:tcp] = Foo.new
gets
it = ro[:unix]
p [it, it.foo(1)]
gets
p it.bar('2') {|n| n * 3}
gets

28
sample/drb/gw_cu.rb Normal file
View file

@ -0,0 +1,28 @@
require 'drb/drb'
require 'drb/unix'
class Foo
include DRbUndumped
def foo(n)
n + n
end
def bar(n)
yield(n) + yield(n)
end
end
DRb.start_service('drubyunix:', nil)
puts DRb.uri
ro = DRbObject.new(nil, ARGV.shift)
ro[:unix] = Foo.new
gets
it = ro[:tcp]
p [it, it.foo(1)]
gets
p it.bar('2') {|n| n * 3}
gets

9
sample/drb/gw_s.rb Normal file
View file

@ -0,0 +1,9 @@
require 'drb/drb'
require 'drb/unix'
require 'drb/gw'
DRb.install_id_conv(DRb::GWIdConv.new)
gw = DRb::GW.new
s1 = DRb::DRbServer.new(ARGV.shift, gw)
s2 = DRb::DRbServer.new(ARGV.shift, gw)
gets

22
sample/drb/holderc.rb Normal file
View file

@ -0,0 +1,22 @@
require 'drb/drb'
begin
there = ARGV.shift || raise
rescue
$stderr.puts("usage: #{$0} <server_uri>")
exit 1
end
DRb.start_service()
ro = DRbObject.new(nil, there)
ary = []
10.times do
ary.push(ro.gen)
end
sleep 5 if $DEBUG
ary.each do |e|
p e.sample([1])
end

64
sample/drb/holders.rb Normal file
View file

@ -0,0 +1,64 @@
=begin
= How to play.
== with timeridconv:
% ruby -d holders.rb
druby://yourhost:1234
% ruby holderc.rb druby://yourhost:1234
== without timeridconv:
% ruby holders.rb
druby://yourhost:1234
% ruby holderc.rb druby://yourhost:1234
=end
require 'drb/drb'
class DRbEx3
include DRbUndumped
def initialize(n)
@v = n
end
def sample(list)
sum = 0
list.each do |e|
sum += e.to_i
end
@v * sum
end
end
class DRbEx4
include DRbUndumped
def initialize
@curr = 1
end
def gen
begin
@curr += 1
DRbEx3.new(@curr)
ensure
GC.start
end
end
end
if __FILE__ == $0
if $DEBUG
require 'drb/timeridconv'
DRb.install_id_conv(DRb::TimerIdConv.new(2))
end
DRb.start_service(nil, DRbEx4.new)
puts DRb.uri
puts '[return] to exit'
gets
end

77
sample/drb/http0.rb Normal file
View file

@ -0,0 +1,77 @@
require 'drb/drb'
require 'net/http'
require 'uri'
module DRb
module HTTP0
class StrStream
def initialize(str='')
@buf = str
end
attr_reader :buf
def read(n)
begin
return @buf[0,n]
ensure
@buf[0,n] = ''
end
end
def write(s)
@buf.concat s
end
end
def self.uri_option(uri, config)
return uri, nil
end
def self.open(uri, config)
unless /^http:/ =~ uri
raise(DRbBadScheme, uri) unless uri =~ /^http:/
raise(DRbBadURI, 'can\'t parse uri:' + uri)
end
ClientSide.new(uri, config)
end
class ClientSide
def initialize(uri, config)
@uri = uri
@res = nil
@config = config
@msg = DRbMessage.new(config)
@proxy = ENV['HTTP_PROXY']
end
def close; end
def alive?; false; end
def send_request(ref, msg_id, *arg, &b)
stream = StrStream.new
@msg.send_request(stream, ref, msg_id, *arg, &b)
@reply_stream = StrStream.new
post(@uri, stream.buf)
end
def recv_reply
@msg.recv_reply(@reply_stream)
end
def post(url, data)
it = URI.parse(url)
path = [(it.path=='' ? '/' : it.path), it.query].compact.join('?')
http = Net::HTTP.new(it.host, it.port)
sio = StrStream.new
http.post(path, data, {'Content-Type'=>'application/octetstream;'}) do |str|
sio.write(str)
if @config[:load_limit] < sio.buf.size
raise TypeError, 'too large packet'
end
end
@reply_stream = sio
end
end
end
DRbProtocol.add_protocol(HTTP0)
end

119
sample/drb/http0serv.rb Normal file
View file

@ -0,0 +1,119 @@
require 'webrick'
require 'drb/drb'
require 'drb/http0'
require 'thread'
module DRb
module HTTP0
def self.open_server(uri, config)
unless /^http:/ =~ uri
raise(DRbBadScheme, uri) unless uri =~ /^http:/
raise(DRbBadURI, 'can\'t parse uri:' + uri)
end
Server.new(uri, config)
end
class Callback < WEBrick::HTTPServlet::AbstractServlet
def initialize(config, drb)
@config = config
@drb = drb
@queue = Queue.new
end
def do_POST(req, res)
@req = req
@res = res
@drb.push(self)
@res.body = @queue.pop
@res['content-type'] = 'application/octet-stream;'
end
def req_body
@req.body
end
def reply(body)
@queue.push(body)
end
def close
@queue.push('')
end
end
class Server
def initialize(uri, config)
@uri = uri
@config = config
@queue = Queue.new
setup_webrick(uri)
end
attr_reader :uri
def close
@server.shutdown if @server
@server = nil
end
def push(callback)
@queue.push(callback)
end
def accept
client = @queue.pop
ServerSide.new(client, @config)
end
def setup_webrick(uri)
logger = WEBrick::Log::new($stderr, WEBrick::Log::FATAL)
u = URI.parse(uri)
s = WEBrick::HTTPServer.new(:Port => u.port,
:AddressFamily => Socket::AF_INET,
:BindAddress => u.host,
:Logger => logger,
:ServerType => Thread)
s.mount(u.path, Callback, self)
@server = s
s.start
end
end
class ServerSide
def initialize(callback, config)
@callback = callback
@config = config
@msg = DRbMessage.new(@config)
@req_stream = StrStream.new(@callback.req_body)
end
def close
@callback.close if @callback
@callback = nil
end
def alive?; false; end
def recv_request
begin
@msg.recv_request(@req_stream)
rescue
close
raise $!
end
end
def send_reply(succ, result)
begin
return unless @callback
stream = StrStream.new
@msg.send_reply(stream, succ, result)
@callback.reply(stream.buf)
rescue
close
raise $!
end
end
end
end
end

118
sample/drb/name.rb Normal file
View file

@ -0,0 +1,118 @@
=begin
distributed Ruby --- NamedObject Sample
Copyright (c) 2000-2001 Masatoshi SEKI
=end
=begin
How to play.
* start server
Terminal 1
| % ruby name.rb druby://yourhost:7640
| druby://yourhost:7640
| [return] to exit
* start client
Terminal 2
| % ruby namec.rb druby://yourhost:7640
| #<DRb::DRbObject:0x40164174 @uri="druby://yourhost:7640", @ref="seq">
| #<DRb::DRbObject:0x40163c9c @uri="druby://yourhost:7640", @ref="mutex">
| 1
| 2
| [return] to continue
* restart server
Terminal 1
type [return]
| % ruby name.rb druby://yourhost:7640
| druby://yourhost:7640
| [return] to exit
* continue client
Terminal 2
type [return]
| 1
| 2
=end
require 'thread.rb'
require 'drb/drb'
module DRbNamedObject
DRbNAMEDICT = {}
attr_reader(:drb_name)
def drb_name=(name)
@drb_name = name
Thread.exclusive do
raise(IndexError, name) if DRbNAMEDICT[name]
DRbNAMEDICT[name] = self
end
end
end
class DRbNamedIdConv < DRb::DRbIdConv
def initialize
@dict = DRbNamedObject::DRbNAMEDICT
end
def to_obj(ref)
@dict.fetch(ref) do super end
end
def to_id(obj)
if obj.kind_of? DRbNamedObject
return obj.drb_name
else
return super
end
end
end
class Seq
include DRbUndumped
include DRbNamedObject
def initialize(v, name)
@counter = v
@mutex = Mutex.new
self.drb_name = name
end
def next_value
@mutex.synchronize do
@counter += 1
return @counter
end
end
end
class Front
def initialize
seq = Seq.new(0, 'seq')
mutex = Mutex.new
mutex.extend(DRbUndumped)
mutex.extend(DRbNamedObject)
mutex.drb_name = 'mutex'
@name = {}
@name['seq'] = seq
@name['mutex'] = mutex
end
def [](k)
@name[k]
end
end
if __FILE__ == $0
uri = ARGV.shift
name_conv = DRbNamedIdConv.new
DRb.install_id_conv(name_conv)
DRb.start_service(uri, Front.new)
puts DRb.uri
puts '[return] to exit'
gets
end

36
sample/drb/namec.rb Normal file
View file

@ -0,0 +1,36 @@
=begin
distributed Ruby --- NamedObject Sample Client
Copyright (c) 2000-2001 Masatoshi SEKI
=end
require 'drb/drb'
begin
there = ARGV.shift || raise
rescue
puts "usage: #{$0} <server_uri>"
exit 1
end
DRb.start_service()
ro = DRbObject.new(nil, there)
seq = ro["seq"]
mutex = ro["mutex"]
p seq
p mutex
mutex.synchronize do
p seq.next_value
p seq.next_value
end
puts '[return] to continue'
gets
mutex.synchronize do
p seq.next_value
p seq.next_value
end

View file

@ -0,0 +1,214 @@
#!/usr/local/bin/ruby
# TupleSpace
# Copyright (c) 1999-2000 Masatoshi SEKI
# You can redistribute it and/or modify it under the same terms as Ruby.
require 'thread'
class TupleSpace
class Template
def initialize(list)
@list = list
@check_idx = []
@list.each_with_index do |x, i|
@check_idx.push i if x
end
@size = @list.size
end
attr :size
alias length size
def match(tuple)
return nil if tuple.size != self.size
@check_idx.each do |i|
unless @list[i] === tuple[i]
return false
end
end
return true
end
end
def initialize
@que = {}
@waiting = {}
@que.taint # enable tainted comunication
@waiting.taint
self.taint
end
def wakeup_waiting(tuple)
sz = tuple.length
return nil unless @waiting[sz]
x = nil
i = -1
found = false
@waiting[sz] = @waiting[sz].find_all { |x|
if x[0].match(tuple)
begin
x[1].wakeup
rescue ThreadError
end
false
else
true
end
}
end
def put_waiting(template, thread)
sz = template.length
@waiting[sz] = [] unless @waiting[sz]
@waiting[sz].push([Template.new(template), thread])
end
private :wakeup_waiting
private :put_waiting
def get_que(template)
sz = template.length
return nil unless @que[sz]
template = Template.new(template)
x = nil
i = -1
found = false
@que[sz].each_with_index do |x, i|
if template.match(x)
found = true
break
end
end
return nil unless found
@que[sz].delete_at(i)
return x
end
def put_que(tuple)
sz = tuple.length
@que[sz] = [] unless @que[sz]
@que[sz].push tuple
end
private :get_que
private :put_que
def out(*tuples)
tuples.each do |tuple|
Thread.critical = true
put_que(tuple)
wakeup_waiting(tuple)
Thread.critical = false
end
end
alias put out
alias write out
def in(template, non_block=false)
begin
loop do
Thread.critical = true
tuple = get_que(template)
unless tuple
if non_block
raise ThreadError, "queue empty"
end
put_waiting(template, Thread.current)
Thread.stop
else
return tuple
end
end
ensure
Thread.critical = false
end
end
alias get in
alias take in
def rd(template, non_block=false)
tuple = self.in(template, non_block)
out(tuple)
tuple
end
alias read rd
def mv(dest, template, non_block=false)
tuple = self.in(template, non_block)
begin
dest.out(tuple)
rescue
self.out(tuple)
end
end
alias move mv
end
if __FILE__ == $0
ts = TupleSpace.new
clients = []
servers = []
def server(ts, id)
Thread.start {
loop do
req = ts.in(['req', nil, nil])
ac = req[1]
num = req[2]
sleep id
ts.out([ac, id, num, num * num])
end
}
end
def client(ts, n)
Thread.start {
ac = Object.new
tuples = (1..10).collect { |i|
['req', ac, i * 10 + n]
}
ts.out(*tuples)
ts.out(tuples[0])
puts "out: #{n}"
11.times do |i|
ans = ts.in([ac, nil, nil, nil])
puts "client(#{n}) server(#{ans[1]}) #{ans[2]} #{ans[3]}"
end
}
end
def watcher(ts)
Thread.start {
loop do
begin
sleep 1
p ts.rd(['req', nil, nil], true)
rescue ThreadError
puts "'req' not found."
end
end
}
end
(0..3).each do |n|
servers.push(server(ts, n))
end
(1..6).each do |n|
clients.push(client(ts, n))
end
(1..3).each do
watcher(ts)
end
clients.each do |t|
t.join
end
end

7
sample/drb/rinda_ts.rb Normal file
View file

@ -0,0 +1,7 @@
require 'drb/drb'
require 'rinda/tuplespace'
uri = ARGV.shift
DRb.start_service(uri, Rinda::TupleSpace.new)
puts DRb.uri
DRb.thread.join

17
sample/drb/rindac.rb Normal file
View file

@ -0,0 +1,17 @@
require 'drb/drb'
require 'rinda/rinda'
uri = ARGV.shift || raise("usage: #{$0} <server_uri>")
DRb.start_service
ts = Rinda::TupleSpaceProxy.new(DRbObject.new(nil, uri))
(1..10).each do |n|
ts.write(['sum', DRb.uri, n])
end
(1..10).each do |n|
ans = ts.take(['ans', DRb.uri, n, nil])
p [ans[2], ans[3]]
end

18
sample/drb/rindas.rb Normal file
View file

@ -0,0 +1,18 @@
require 'drb/drb'
require 'rinda/rinda'
def do_it(v)
puts "do_it(#{v})"
v + v
end
uri = ARGV.shift || raise("usage: #{$0} <server_uri>")
DRb.start_service
ts = Rinda::TupleSpaceProxy.new(DRbObject.new(nil, uri))
while true
r = ts.take(['sum', nil, nil])
v = do_it(r[2])
ts.write(['ans', r[1], r[2], v])
end

30
sample/drb/ring_echo.rb Normal file
View file

@ -0,0 +1,30 @@
require 'drb/drb'
require 'drb/eq'
require 'rinda/ring'
require 'thread'
class RingEcho
include DRbUndumped
def initialize(name)
@name = name
end
def echo(str)
"#{@name}: #{str}"
end
end
DRb.start_service
renewer = Rinda::SimpleRenewer.new
finder = Rinda::RingFinger.new
ts = finder.lookup_ring_any
ts.read_all([:name, :RingEcho, nil, nil]).each do |tuple|
p tuple[2]
puts tuple[2].echo('Hello, World') rescue nil
end
ts.write([:name, :RingEcho, RingEcho.new(DRb.uri), ''], renewer)
$stdin.gets

View file

@ -0,0 +1,30 @@
require 'rinda/ring'
require 'drb/drb'
class Inspector
def initialize
end
def primary
Rinda::RingFinger.primary
end
def list_place
Rinda::RingFinger.to_a
end
def list(idx = -1)
if idx < 0
ts = primary
else
ts = list_place[idx]
raise "RingNotFound" unless ts
end
ts.read_all([:name, nil, nil, nil])
end
end
def main
DRb.start_service
r = Inspector.new
end

25
sample/drb/ring_place.rb Normal file
View file

@ -0,0 +1,25 @@
require 'drb/drb'
require 'rinda/ring'
require 'rinda/tuplespace'
unless $DEBUG
# Run as a daemon...
exit!( 0 ) if fork
Process.setsid
exit!( 0 ) if fork
end
DRb.start_service(ARGV.shift)
ts = Rinda::TupleSpace.new
place = Rinda::RingServer.new(ts)
if $DEBUG
puts DRb.uri
DRb.thread.join
else
STDIN.reopen('/dev/null')
STDOUT.reopen('/dev/null', 'w')
STDERR.reopen('/dev/null', 'w')
DRb.thread.join
end

91
sample/drb/simpletuple.rb Normal file
View file

@ -0,0 +1,91 @@
#!/usr/local/bin/ruby
# SimpleTupleSpace
# Copyright (c) 1999-2000 Masatoshi SEKI
# You can redistribute it and/or modify it under the same terms as Ruby.
require 'thread'
class SimpleTupleSpace
def initialize
@hash = {}
@waiting = {}
@hash.taint
@waiting.taint
self.taint
end
def out(key, obj)
Thread.critical = true
@hash[key] ||= []
@waiting[key] ||= []
@hash[key].push obj
begin
t = @waiting[key].shift
@waiting.delete(key) if @waiting[key].length == 0
t.wakeup if t
rescue ThreadError
retry
ensure
Thread.critical = false
end
end
def in(key)
Thread.critical = true
@hash[key] ||= []
@waiting[key] ||= []
begin
loop do
if @hash[key].length == 0
@waiting[key].push Thread.current
Thread.stop
else
return @hash[key].shift
end
end
ensure
@hash.delete(key) if @hash[key].length == 0
Thread.critical = false
end
end
end
if __FILE__ == $0
ts = SimpleTupleSpace.new
clients = []
servers = []
def server(ts)
Thread.start {
loop do
req = ts.in('req')
ac = req[0]
num = req[1]
ts.out(ac, num * num)
end
}
end
def client(ts, n)
Thread.start {
ac = Object.new
ts.out('req', [ac, n])
ans = ts.in(ac)
puts "#{n}: #{ans}"
}
end
3.times do
servers.push(server(ts))
end
(1..6).each do |n|
clients.push(client(ts, n))
end
clients.each do |t|
t.join
end
end

21
sample/drb/speedc.rb Normal file
View file

@ -0,0 +1,21 @@
#!/usr/local/bin/ruby
uri = ARGV.shift || raise("usage: #{$0} URI")
N = (ARGV.shift || 100).to_i
case uri
when /^tcpromp:/, /^unixromp:/
require 'romp'
client = ROMP::Client.new(uri, false)
foo = client.resolve("foo")
when /^druby:/
require 'drb/drb'
DRb.start_service
foo = DRbObject.new(nil, uri)
end
N.times do |n|
foo.foo(n)
end

33
sample/drb/speeds.rb Normal file
View file

@ -0,0 +1,33 @@
class Foo
attr_reader :i
def initialize
@i = 0
end
def foo(i)
@i = i
i + i
end
end
# server = ROMP::Server.new('tcpromp://localhost:4242', nil, true)
uri = ARGV.shift || raise("usage: #{$0} URI")
foo = Foo.new
case uri
when /^tcpromp:/, /^unixromp:/
require 'romp'
server = ROMP::Server.new(uri, nil, true)
server.bind(foo, "foo")
when /^druby:/
require 'drb/drb'
DRb.start_service(uri, Foo.new)
end
puts '[enter] to exit'
gets