DRb and Rinda

1,727 views

Published on

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
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,727
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
19
Comments
0
Likes
1
Embeds 0
No embeds

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
  • DRb and Rinda

    1. 1. A Tour of DistributedProgramming with Rubywith Mark Bates
    2. 2. Mark Bates
    3. 3. Mark BatesRubyist since 2005
    4. 4. Mark BatesRubyist since 2005Freelance Consultant
    5. 5. Mark BatesRubyist since 2005Freelance ConsultantMusician
    6. 6. Mark BatesRubyist since 2005Freelance ConsultantMusicianAuthor
    7. 7. DistributedProgrammingwith RubyAddison-Wesley (2010)http://books.markbates.com
    8. 8. Programmingin CoffeeScriptAddison-Wesley (2012)http://books.markbates.com
    9. 9. WHO? WHAT? WHEN? WHY? NOT SO MUCH HOW
    10. 10. No HOW?What’s the point?
    11. 11. RMI - REMOTE METHOD INVOCATIONKNOWN ALIASES: DRB, DRUBY, DISTRIBUTED RUBY
    12. 12. What?
    13. 13. What?Call methods remotely
    14. 14. What?Call methods remotelyStandard Library, no additional packages
    15. 15. What?Call methods remotelyStandard Library, no additional packagesEasy and Powerful
    16. 16. What?Call methods remotelyStandard Library, no additional packagesEasy and PowerfulEXTREMELY DANGEROUS!!
    17. 17. When/Why?
    18. 18. When/Why?Fast and Easy
    19. 19. When/Why?Fast and EasyBuilt into standard library
    20. 20. When/Why?Fast and EasyBuilt into standard libraryAlmost zero configuration
    21. 21. When/Why?Fast and EasyBuilt into standard libraryAlmost zero configurationNo need for controllers, JSON, XML, web servers,etc...
    22. 22. When/Why?Fast and EasyBuilt into standard libraryAlmost zero configurationNo need for controllers, JSON, XML, web servers,etc...Closed Environment
    23. 23. Demo
    24. 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. 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. 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. 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. 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. 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. 30. Danger!
    31. 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. 32. RINDAKNOWN ALIASES: NONE
    33. 33. What?
    34. 34. What?DRb Service Registry
    35. 35. What?DRb Service Registry“configure-less”
    36. 36. What?DRb Service Registry“configure-less”Redundant
    37. 37. When/Why?
    38. 38. When/Why?Simple to Setup
    39. 39. When/Why?Simple to SetupNo “hard-coded” IPs/Ports
    40. 40. When/Why?Simple to SetupNo “hard-coded” IPs/PortsSelf-Describing
    41. 41. When/Why?Simple to SetupNo “hard-coded” IPs/PortsSelf-DescribingRedundant
    42. 42. When/Why?Simple to SetupNo “hard-coded” IPs/PortsSelf-DescribingRedundantInterprocess Communication
    43. 43. Service 1 Service 2 RingServerService 3 Service 4
    44. 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. 45. Demo
    46. 46. require drbrequire rinda/ringrequire rinda/tuplespaceDRb.start_serviceputs "Starting RingServer..."Rinda::RingServer.new(Rinda::TupleSpace.new)puts "...RingServer started."DRb.thread.join
    47. 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. 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. 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. 50. Thank You
    51. 51. DistributedProgrammingwith Rubyhttp://books.markbates.comhttp://metabates.comhttp://github.com/markbates

    ×