DRb at the Ruby Drink-up of Sophia, December 2011


Published on

Presented at the Ruby Drink-up of Sophia Antipolis on the 6th of December 2011 by Nicolas Bondoux (@nicolas_bondoux).

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

DRb at the Ruby Drink-up of Sophia, December 2011

  1. 1. DRb: an easy distributed objects framework for Ruby Ruby Drink-up of Sophia-Antipolis Nicolas Bondoux 06/12/2011
  2. 2. Quick Presentation (1) <ul><li>Allows do share ruby objects between remote processes
  3. 3. Transparent usage
  4. 4. No IDL; no need to share class definitions
  5. 5. DRb main classes are in standard library </li></ul>
  6. 6. Quick Presentation (2) <ul><li>A light library implemented in ruby
  7. 7. Implemented network layers tcp, unix sockets, tcp+ssl </li></ul>
  8. 8. Quick example (1) <ul><li>On Server side: </li></ul>require 'drb' MyURI = &quot;druby://; class SimpleServer include DRb::DRbUndumped def initialize @i = 0 end def helloWorld puts &quot;Hello World&quot; @i += 1 return @i end def broken puts i end end # start a server with a new SimpleServer as front object DRb.start_service(MyURI, SimpleServer.new) # wait for the server thread to suicide DRb.thread.join
  9. 9. Quick example (2) <ul><li>On client side </li></ul>r equire 'drb' MyURI = &quot;druby://; server = DRb::DRbObject.new(nil,MyURI) puts server.helloWorld # display 1 # server puts “Hello World” puts server.broken #NameError: undefined local variable or method `i' for #<SimpleServer:0x7ffe9814af20 @i=4> # from (druby:// (irb):40:in `broken' # from (irb):24 # from :0
  10. 10. DRb classes: DRbObject <ul><li>The fundamental type in Drb
  11. 11. Acts as a proxy for a remote object
  12. 12. Concretely, its fields are: </li><ul><li>@uri: address of the DRbServer providing the object
  13. 13. @ref: id of the object within the remote process </li></ul><li>Forwards method calls to the remote object </li></ul>
  14. 14. The URIs <ul><li>“druby://” -> tcp uri
  15. 15. “drbunix:/tmp/toto” -> unix socket </li></ul>
  16. 16. DRb classes: DRbServer <ul><li>Any process publishing a local must have a DrbServer thread running </li><ul><li>Launched with DRb.start_service </li></ul><li>A front object may be associated to a DrbServer (act as default object when building a DRbObject from the URI)
  17. 17. DRbObject.new (obj, nil) will holds the ref of obj as well as the URI of current server (Drb.uri) </li></ul>
  18. 18. DRbObject: method calls <ul><li>parameters and return value transmission: </li><ul><li>Either can be copied between process </li><ul><li>(both processes need then to know their definitions) </li></ul><li>Or can have a DrbObject referencing them copied instead </li><ul><li>These objects will then be shared between processes </li></ul></ul><li>exceptions are propagated the same way than with local calls </li></ul>
  19. 19. DrbObject example # server side require 'drb' MyURI = &quot;druby://; $s = &quot;Toto&quot; class SimpleServer include DRb::DRbUndumped def s_DRbObject return DRbObject.new($s) end def s return $s end def s_clone return String.new($s) end end DRb.start_service(MyURI, SimpleServer.new) #on client side: require 'drb' MyURI = &quot;druby://; server = DRb::DRbObject.new(nil,MyURI) s = server.s puts s puts s.class #String s.concat(&quot; updated!&quot;) puts server.s_clone # display &quot;Toto&quot; s = server.s_DRbObject # DRb::DRbObject s.concat(&quot; updated !&quot;) puts server.s_clone # display &quot;Toto updated !&quot;
  20. 20. Undumped objects <ul><li>By default, methods calls copy their parameters without conversion to DRbObject
  21. 21. Objects that cannot be marshalled are always passed as DRbObjects: Proc, IO, singletons, or any object referencing one of them
  22. 22. Objects that include DRb::DRbUndumped are always passed as DRbObject </li></ul>
  23. 23. DRbUndumped example <ul><li>Continuing previous example: </li></ul># server side $s = &quot;Titi&quot; $s.extend DRbUndumped #on client side: s = server.s puts s.class # DRb::DRbObject s.concat(&quot; updated !&quot;) puts server.s_clone # display &quot;Titi updated !&quot;
  24. 24. Complex example with a Proc # server require 'drb' MyURI = &quot;druby://; class Container def initialize @t = [] end def push o @t.push o end def each(&block) @t.each(&block) end end s = Container.new DRb.start_service(MyURI, s,{:safe_level => 1}) # client require 'drb' MyURI = &quot;druby://; class Box include DRbUndumped attr_accessor :v def initialize v @v = v end end # needed to share local objects with the server: DRb.start_service s = DRbObject.new(nil, MyURI) a = Box.new(1) b = Box.new(2) s.push a s.push b s.each{ |i| puts i.class i.v = (i.v * 2) } # Box # Box # => block is called in local # => its parameters are converted back to local objects puts a.v # 2 puts b.v # 4
  25. 25. Local DRbObjects <ul><li>Methods call on DRbObject referencing a local instance are just normal method calls
  26. 26. Unmarshaller converts a DrbObject on local object as a ref on local object </li></ul>
  27. 27. Things good to know <ul><li>Beware garbage collection! An object won't be kept alive because a DRbObject points on it.
  28. 28. A server creates a thread by client connection </li><ul><li>-> do not forget your mutexes! </li></ul><li>Security: </li><ul><li>ACL system to control authorized clients
  29. 29. $SAFE variable should be set to 1 to prevent remote eval (can be set as parameter of the DRbServer) </li></ul></ul>
  30. 30. IdConv <ul><li>Drb allows to choose the mapping engine between id and objects.
  31. 31. Three implementations provided: </li><ul><li>DRb::DRbIdConv </li><ul><li>Basic object space conversion </li></ul><li>Drb::TimerIdConv </li><ul><li>Prevent GC of an object for a certain amount of time after the last access </li></ul><li>Drb::GWIdConv </li><ul><li>The server act as a gateway for remote objects </li></ul></ul></ul>
  32. 32. Any Question ?