• Like
DRb and Rinda
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

DRb and Rinda

  • 1,084 views
Published

A fun filled tour through distributed programming with the Ruby standard library. …

A fun filled tour through distributed programming with the Ruby standard library.

Presented on February 2nd, 2012 at RubyFuza in Cape Town, South Africa.

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,084
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
13
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Transcript

  • 1. A Tour of DistributedProgramming with Rubywith Mark Bates
  • 2. Mark Bates
  • 3. Mark BatesRubyist since 2005
  • 4. Mark BatesRubyist since 2005Freelance Consultant
  • 5. Mark BatesRubyist since 2005Freelance ConsultantMusician
  • 6. Mark BatesRubyist since 2005Freelance ConsultantMusicianAuthor
  • 7. DistributedProgrammingwith RubyAddison-Wesley (2010)http://books.markbates.com
  • 8. Programmingin CoffeeScriptAddison-Wesley (2012)http://books.markbates.com
  • 9. WHO? WHAT? WHEN? WHY? NOT SO MUCH HOW
  • 10. No HOW?What’s the point?
  • 11. RMI - REMOTE METHOD INVOCATIONKNOWN ALIASES: DRB, DRUBY, DISTRIBUTED RUBY
  • 12. What?
  • 13. What?Call methods remotely
  • 14. What?Call methods remotelyStandard Library, no additional packages
  • 15. What?Call methods remotelyStandard Library, no additional packagesEasy and Powerful
  • 16. What?Call methods remotelyStandard Library, no additional packagesEasy and PowerfulEXTREMELY DANGEROUS!!
  • 17. When/Why?
  • 18. When/Why?Fast and Easy
  • 19. When/Why?Fast and EasyBuilt into standard library
  • 20. When/Why?Fast and EasyBuilt into standard libraryAlmost zero configuration
  • 21. When/Why?Fast and EasyBuilt into standard libraryAlmost zero configurationNo need for controllers, JSON, XML, web servers,etc...
  • 22. When/Why?Fast and EasyBuilt into standard libraryAlmost zero configurationNo need for controllers, JSON, XML, web servers,etc...Closed Environment
  • 23. Demo
  • 24. require drbrequire timeclass UserService def authenticate(user, password) puts "attempting to authenticate: #{user}" if user == markbates && password == password return {:user => markbates, :email => mark@markbates.com, :created_at => Time.parse(August 24 1976)} end return !!SECURITY BREACH!! endendputs Starting UserService...DRb.start_service("druby://127.0.0.1:61676", UserService.new)DRb.thread.join
  • 25. require drbuser_service = DRbObject.new_with_uri("druby://127.0.0.1:61676")loop do puts "username:" user = gets.chomp puts "password:" pass = gets.chomp puts user_service.authenticate(user, pass)end
  • 26. require drbrequire timerequire ./userclass UserService def authenticate(user, password) puts "attempting to authenticate: #{user}" if user == markbates && password == password return User.new({:user => markbates, :email => mark@markbates.com, :created_at => Time.parse(August 241976)}) end return !!SECURITY BREACH!! endendputs Starting UserService...DRb.start_service("druby://127.0.0.1:61676", UserService.new)DRb.thread.join
  • 27. class User attr_accessor :user, :email, :created_at def initialize(attributes) attributes.each {|k, v| self.send("#{k}=", v)} end def email @email end def to_s "<User: user:#{self.user}, email:#{self.email},created_at:#{self.created_at}>" endend
  • 28. class User attr_accessor :user, :email, :created_at def initialize(attributes) attributes.each {|k, v| self.send("#{k}=", v)} end def email @email end def to_s "<User: user:#{self.user}, email:#{self.email},created_at:#{self.created_at}>" endend
  • 29. class User include DRbUndumped attr_accessor :user, :email, :created_at def initialize(attributes) attributes.each {|k, v| self.send("#{k}=", v)} end def email @email end def to_s "<User: user:#{self.user}, email:#{self.email},created_at:#{self.created_at}>" endend
  • 30. Danger!
  • 31. require drb# !!! UNSAFE CODE DO NOT RUN !!!ro = DRbObject::new_with_uri("druby://127.0.0.1:61676")class << ro undef :instance_evalendro.instance_eval("`rm -rf *`")
  • 32. RINDAKNOWN ALIASES: NONE
  • 33. What?
  • 34. What?DRb Service Registry
  • 35. What?DRb Service Registry“configure-less”
  • 36. What?DRb Service Registry“configure-less”Redundant
  • 37. When/Why?
  • 38. When/Why?Simple to Setup
  • 39. When/Why?Simple to SetupNo “hard-coded” IPs/Ports
  • 40. When/Why?Simple to SetupNo “hard-coded” IPs/PortsSelf-Describing
  • 41. When/Why?Simple to SetupNo “hard-coded” IPs/PortsSelf-DescribingRedundant
  • 42. When/Why?Simple to SetupNo “hard-coded” IPs/PortsSelf-DescribingRedundantInterprocess Communication
  • 43. Service 1 Service 2 RingServerService 3 Service 4
  • 44. Where can I find Service X? RingServer Listening on a broadcast UDP Service X: 192.168.1.12 address Client192.168.1.100 Hi Service X @ 192.168.1.12 Service @ 192.168.1.12 Hi There 192.168.1.100!
  • 45. Demo
  • 46. require drbrequire rinda/ringrequire rinda/tuplespaceDRb.start_serviceputs "Starting RingServer..."Rinda::RingServer.new(Rinda::TupleSpace.new)puts "...RingServer started."DRb.thread.join
  • 47. require drbrequire timerequire ./userrequire rinda/ringclass UserService include DRbUndumped def authenticate(user, password) puts "attempting to authenticate: #{user}" if user == markbates && password == password return User.new({:user => markbates, :email => mark@markbates.com, :created_at => Time.parse(August 24 1976)}) end return !!SECURITY BREACH!! endendDRb.start_servicering_server = Rinda::RingFinger.primaryring_server.write([:user_service, :UserService, UserService.new, A simple Auth Service], Rinda::SimpleRenewer.new)DRb.thread.join
  • 48. require rinda/ringDRb.start_servicering_server = Rinda::RingFinger.primaryservice = ring_server.read([:user_service, nil, nil, nil])user_service = service[2]loop do puts "username:" user = gets.chomp puts "password:" pass = gets.chomp puts user_service.authenticate(user, pass)end
  • 49. require rinda/ringDRb.start_servicering_server = Rinda::RingFinger.primaryservices = ring_server.read_all([nil, nil, nil, nil])puts "Services on #{ring_server.__drburi}"services.each do |service| puts "#{service[0]}: #{service[1]} on#{service[2].__drburi} - #{service[3]}"end
  • 50. Thank You
  • 51. DistributedProgrammingwith Rubyhttp://books.markbates.comhttp://metabates.comhttp://github.com/markbates