requires=
classes=DRb=ExtServManager
methods=
sublibraries=
is_sublibrary=true
category=

[[c:DRb::ExtServManager]] を定義しているライブラリ。

DRb::ExtServManager は drb で実現されたサービスブローカーです。
個々のサービスは [[lib:drb/extserv]] で定義されている
[[c:DRb::ExtServ]] を用いて実装します。
DRb::ExtServManager
はクライアントの要求に応じて個々のサービスを
サブプロセスとして起動し、各サービスを表す DRb::ExtServ オブジェクト
をリモートオブジェクトとしてクライアントに渡します。

このライブラリは簡易的なもので、あまりメンテナンスもされていないので、
本格的な用途にはこのライブラリを参考にして実装してください。


=== Example

以下の例を実行するためには、まず server.rb を起動し、その後 client.rb を
動かします。service.rb は server.rb が client.rb からサービスを要求された
時に起動されます。また、stop.rbを用いて 



server.rb: 
  require 'drb/drb'
  require 'drb/extservm'
  
  Dir.chdir(File.dirname(__FILE__))
  # サービスを起動するコマンドを指定する
  # コマンドは文字列配列、もしくは文字列で指定できる
  # サブプロセスの起動は Kernel.#spawn でなされる
  #
  # サブプロセスを起動するときは、ここに指定したパラメータに加えて
  # さらに2つのパラメータ(サーバの druby URI とサービス名)が渡されます
  DRb::ExtServManager.command["No1"] = %w(ruby service.rb service1)
  DRb::ExtServManager.command["No2"] = %w(ruby service.rb service2)
  
  # ExtServManager オブジェクトを生成して
  # drb の front object に指定する
  s = DRb::ExtServManager.new
  DRb.start_service("druby://localhost:10234", s)
  
  # drb のプロセスの終了を待つ
  DRb.thread.join

service.rb:
  require 'drb/drb'
  require 'drb/extserv'
  
  # サービスを表すクラス
  class Service
    include DRb::DRbUndumped
  
    def initialize(service_name)
      @service_name = service_name
    end
    
    def hello
      "You invoke #{@service_name}"
    end
  end
  
  puts "Start #{ARGV[0]}"
  # ARGV の最後2つを除いた部分は ExtServManager.command で
  # 指定した引数が渡される
  front = Service.new(ARGV[0])
  
  # 通信のため drb を起動する
  # ポート番号に 0 を指定すると ephemeral port から適当なポート番号が
  # 選ばれる 
  server = DRb::DRbServer.new("druby://localhost:0", front)
  
  # ARGV の最後の2つと DRbServer オブジェクトを ExtServ.new に渡す。
  # これによってブローカープロセスにサービスの
  # 窓口となる ExtServ オブジェクトを渡す
  es = DRb::ExtServ.new(ARGV[1], ARGV[2], server)
  
  # サーバスレッドの停止を待つ
  DRb.thread.join
  # サービスを DRb::ExtServ#stop_service で止めると、サーバスレッドが
  # 終了するため、以下の行が実行される
  puts "Stop #{ARGV[0]}"

client.rb:
  require 'drb/drb'
  
  DRb.start_service
  s = DRbObject.new_with_uri("druby://localhost:10234")
  
  # No1 と名付けられたサービスを呼び出す
  service1 = s.service("No1").front
  p service1.hello # => "service1"
  
  # No2 と名付けられたサービスを呼び出す
  service2 = s.service("No2").front
  p service2.hello # => "service2"

stop.rb:
  require 'drb/drb'
  
  DRb.start_service
  s = DRbObject.new_with_uri("druby://localhost:10234")
  s.service(ARGV[0]).stop_service
