Slide 1

Slide 1 text

@[email protected] / @kkuchta x = "this is a micro service"

Slide 2

Slide 2 text

@[email protected] / @kkuchta x = "this is a micro service"

Slide 3

Slide 3 text

@[email protected] / @kkuchta x = "this is a micro service"

Slide 4

Slide 4 text

@[email protected] / @kkuchta Microservices What do we know

Slide 5

Slide 5 text

@[email protected] / @kkuchta Microservices What do we know A. Regular services, but smaller

Slide 6

Slide 6 text

@[email protected] / @kkuchta Microservices What do we know A. Regular services, but smaller B. Better than services

Slide 7

Slide 7 text

@[email protected] / @kkuchta Microservices What do we know A. Regular services, but smaller B. Better than services C. Smaller = better

Slide 8

Slide 8 text

@[email protected] / @kkuchta Microservices What is the optimal size?

Slide 9

Slide 9 text

@[email protected] / @kkuchta Microservices What is the optimal size? 1. Concept

Slide 10

Slide 10 text

@[email protected] / @kkuchta Microservices What is the optimal size? 1. Concept 2. Model

Slide 11

Slide 11 text

@[email protected] / @kkuchta Microservices What is the optimal size? 1. Concept 2. Model 3. Concern

Slide 12

Slide 12 text

@[email protected] / @kkuchta Microservices What is the optimal size?

Slide 13

Slide 13 text

@[email protected] / @kkuchta Microservices What is the optimal size?

Slide 14

Slide 14 text

@[email protected] / @kkuchta x = SomeObject.new

Slide 15

Slide 15 text

@[email protected] / @kkuchta Microservices Every goddamn object local.rb remote.rb

Slide 16

Slide 16 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts "hi" end end local.rb remote.rb

Slide 17

Slide 17 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts "hi" end end obj = SomeClass.new local.rb remote.rb

Slide 18

Slide 18 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts "hi" end end obj = SomeClass.new obj.foo local.rb remote.rb

Slide 19

Slide 19 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts "hi" end end obj = SomeClass.new obj.foo local.rb remote.rb # puts "hi" on remote server

Slide 20

Slide 20 text

@[email protected] / @kkuchta Because Microservices

Slide 21

Slide 21 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo local.rb remote.rb

Slide 22

Slide 22 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote local.rb remote.rb

Slide 23

Slide 23 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote local.rb remote.rb

Slide 24

Slide 24 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote local.rb remote.rb

Slide 25

Slide 25 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote local.rb remote.rb

Slide 26

Slide 26 text

@[email protected] / @kkuchta Everything a Microservice Kevin Kuchta He/him Daybreak Health The worst possible intro to dRuby

Slide 27

Slide 27 text

@[email protected] / @kkuchta Microservices Every goddamn object local.rb remote.rb class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 28

Slide 28 text

@[email protected] / @kkuchta Remote Objects local.rb remote.rb foo = (something) output = foo.bar

Slide 29

Slide 29 text

@[email protected] / @kkuchta Remote Objects local.rb remote.rb foo = (something) output = foo.bar # bar runs over here

Slide 30

Slide 30 text

@[email protected] / @kkuchta dRuby

Slide 31

Slide 31 text

@[email protected] / @kkuchta dRuby $ gem install drb

Slide 32

Slide 32 text

@[email protected] / @kkuchta dRuby the good parts

Slide 33

Slide 33 text

@[email protected] / @kkuchta dRuby the good parts local.rb

Slide 34

Slide 34 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb

Slide 35

Slide 35 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb'

Slide 36

Slide 36 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end

Slide 37

Slide 37 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service(

Slide 38

Slide 38 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555',

Slide 39

Slide 39 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555', RemoteServer.new )

Slide 40

Slide 40 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555', RemoteServer.new ) DRb.thread.join

Slide 41

Slide 41 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb' require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555', RemoteServer.new ) DRb.thread.join

Slide 42

Slide 42 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb' remote = DRbObject.new_with_uri( require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555', RemoteServer.new ) DRb.thread.join

Slide 43

Slide 43 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb' remote = DRbObject.new_with_uri( 'druby://localhost:5555' ) require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555', RemoteServer.new ) DRb.thread.join

Slide 44

Slide 44 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb' remote = DRbObject.new_with_uri( 'druby://localhost:5555' ) remote.foo require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555', RemoteServer.new ) DRb.thread.join

Slide 45

Slide 45 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb require 'drb/drb' remote = DRbObject.new_with_uri( 'druby://localhost:5555' ) remote.foo require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555', RemoteServer.new ) DRb.thread.join

Slide 46

Slide 46 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb $ ruby remote.rb require 'drb/drb' remote = DRbObject.new_with_uri( 'druby://localhost:5555' ) remote.foo require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555', RemoteServer.new ) DRb.thread.join

Slide 47

Slide 47 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb $ ruby local.rb $ ruby remote.rb require 'drb/drb' remote = DRbObject.new_with_uri( 'druby://localhost:5555' ) remote.foo require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555', RemoteServer.new ) DRb.thread.join

Slide 48

Slide 48 text

@[email protected] / @kkuchta dRuby the good parts local.rb remote.rb $ ruby local.rb $ $ ruby remote.rb foo ran here require 'drb/drb' remote = DRbObject.new_with_uri( 'druby://localhost:5555' ) remote.foo require 'drb/drb' class RemoteServer def foo; puts "foo ran here"; end end DRb.start_service( 'druby://localhost:5555', RemoteServer.new ) DRb.thread.join

Slide 49

Slide 49 text

@[email protected] / @kkuchta Creating Remote Objects automagic local.rb remote.rb class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo

Slide 50

Slide 50 text

@[email protected] / @kkuchta Remote Objects automagic local.rb remote.rb class SomeClass def foo; end end object = remote_new(SomeClass) object.foo

Slide 51

Slide 51 text

@[email protected] / @kkuchta Remote Objects automagic *magic* local.rb remote.rb class SomeClass def foo; end end object = remote_new(SomeClass) object.foo

Slide 52

Slide 52 text

@[email protected] / @kkuchta Remote Objects automatic local.rb remote.rb class RemoteNewer def make_new(klass) klass.new() end end DRb.start_service( 'druby://localhost:5555', RemoteNewer.new) class SomeClass # ... end object = remote_new(SomeClass)

Slide 53

Slide 53 text

@[email protected] / @kkuchta Remote Objects automagic local.rb remote.rb class RemoteNewer def make_new(klass) klass.new() end end DRb.start_service( 'druby://localhost:5555', RemoteNewer.new) class SomeClass # ... end r = DRbObject.new_with_uri( 'druby://localhost:5555' ) r.make_new(SomeClass)

Slide 54

Slide 54 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteObject def foo "bar" end end result = remote.foo

Slide 55

Slide 55 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteObject def foo "bar" end end result = remote.foo result.class # string

Slide 56

Slide 56 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteObject def foo SomethingWeird.new end end result = remote.foo

Slide 57

Slide 57 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteObject def foo SomethingWeird.new end end result = remote.foo result.class # Drb::DrbObject

Slide 58

Slide 58 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteObject def foo SomethingWeird.new end end result = remote.foo result.class # Drb::DrbObject result.something()

Slide 59

Slide 59 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteObject def foo SomethingWeird.new end end result = remote.foo result.class # Drb::DrbObject result.something() # ^ proxies method call

Slide 60

Slide 60 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class SomethingWeird include DRb::DRbUndumped end

Slide 61

Slide 61 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteNewer def make_new(klass) klass.new() .extend(DRb::DRbUndumped) end end

Slide 62

Slide 62 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteNewer def make_new(klass) klass.new() .extend(DRb::DRbUndumped) end end class SomeClass # ... end

Slide 63

Slide 63 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteNewer def make_new(klass) klass.new() .extend(DRb::DRbUndumped) end end class SomeClass # ... end r = DRbObject.new_with_uri( 'druby://localhost:5555' )

Slide 64

Slide 64 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteNewer def make_new(klass) klass.new() .extend(DRb::DRbUndumped) end end class SomeClass # ... end r = DRbObject.new_with_uri( 'druby://localhost:5555' ) obj = r.make_new(SomeClass)

Slide 65

Slide 65 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteNewer def make_new(klass) klass.new() .extend(DRb::DRbUndumped) end end class SomeClass # ... end r = DRbObject.new_with_uri( 'druby://localhost:5555' ) obj = r.make_new(SomeClass) obj.class # DRb::DRbObject

Slide 66

Slide 66 text

@[email protected] / @kkuchta Remote Objects proxying local.rb remote.rb class RemoteNewer def make_new(klass) klass.new() .extend(DRb::DRbUndumped) end end

Slide 67

Slide 67 text

@[email protected] / @kkuchta Remote Objects new + newer local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass .new(*rest, **kwargs, &block) .extend(DRb::DRbUndumped) end end

Slide 68

Slide 68 text

@[email protected] / @kkuchta Remote Objects local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass .new(*rest, **kwargs, &block) .extend(DRb::DRbUndumped) end end

Slide 69

Slide 69 text

@[email protected] / @kkuchta Remote Objects putting it together local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass .new(*rest, **kwargs, &block) .extend(DRb::DRbUn dumped) end end

Slide 70

Slide 70 text

@[email protected] / @kkuchta Remote Objects putting it together local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass .new(*rest, **kwargs, &block) .extend(DRb::DRbUn dumped) end end r = DRbObject.new_with_uri( 'druby://localhost:5555')

Slide 71

Slide 71 text

@[email protected] / @kkuchta Remote Objects putting it together local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass .new(*rest, **kwargs, &block) .extend(DRb::DRbUn dumped) end end r = DRbObject.new_with_uri( 'druby://localhost:5555') remote_str = r.make_new( String, "123")

Slide 72

Slide 72 text

@[email protected] / @kkuchta Remote Objects putting it together local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass .new(*rest, **kwargs, &block) .extend(DRb::DRbUn dumped) end end r = DRbObject.new_with_uri( 'druby://localhost:5555') remote_str = r.make_new( String, "123") remote_str.class # Drb::DrbObject

Slide 73

Slide 73 text

@[email protected] / @kkuchta Remote Objects putting it together local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass .new(*rest, **kwargs, &block) .extend(DRb::DRbUn dumped) end end r = DRbObject.new_with_uri( 'druby://localhost:5555') remote_str = r.make_new( String, "123") remote_str.class # Drb::DrbObject remote_str.to_i

Slide 74

Slide 74 text

@[email protected] / @kkuchta Logging Remote Objects it's login' time local.rb remote.rb module InvokeMethodWithLogging def perform result = super @msg_id && ( puts "remote: #{@msg_id}" ) result end end class DRb::DRbServer::InvokeMethod prepend InvokeMethodWithLogging end

Slide 75

Slide 75 text

@[email protected] / @kkuchta Logging Remote Objects it's login' time local.rb remote.rb module InvokeMethodWithLogging def perform result = super @msg_id && ( puts "remote: #{@msg_id}" ) result end end class DRb::DRbServer::InvokeMethod prepend InvokeMethodWithLogging end

Slide 76

Slide 76 text

@[email protected] / @kkuchta class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass.new(*rest, **kwargs, &block).extend(DRb::DRbUnd umped) end end Remote Objects it's log-o-clock local.rb remote.rb r = DRbObject.new_with_uri( 'druby://localhost:5555') remote_str = r.make_new( String, "123") remote_str.class # Drb::DrbObject remote_str.to_i

Slide 77

Slide 77 text

@[email protected] / @kkuchta class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass.new(*rest, **kwargs, &block).extend(DRb::DRbUnd umped) end end Remote Objects it's log-o-clock local.rb remote.rb $ remote.rb r = DRbObject.new_with_uri( 'druby://localhost:5555') remote_str = r.make_new( String, "123") remote_str.class # Drb::DrbObject remote_str.to_i

Slide 78

Slide 78 text

@[email protected] / @kkuchta class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass.new(*rest, **kwargs, &block).extend(DRb::DRbUnd umped) end end Remote Objects it's log-o-clock local.rb remote.rb $ remote.rb remote: make_new r = DRbObject.new_with_uri( 'druby://localhost:5555') remote_str = r.make_new( String, "123") remote_str.class # Drb::DrbObject remote_str.to_i

Slide 79

Slide 79 text

@[email protected] / @kkuchta class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass.new(*rest, **kwargs, &block).extend(DRb::DRbUnd umped) end end Remote Objects it's log-o-clock local.rb remote.rb $ remote.rb remote: make_new remote: to_i r = DRbObject.new_with_uri( 'druby://localhost:5555') remote_str = r.make_new( String, "123") remote_str.class # Drb::DrbObject remote_str.to_i

Slide 80

Slide 80 text

@[email protected] / @kkuchta Remote Objects Remote Object Everywhere local.rb remote.rb

Slide 81

Slide 81 text

@[email protected] / @kkuchta Remote Objects Remote Object Everywhere local.rb remote.rb remote = DRbObject .new_with_uri('druby://localhost:5555')

Slide 82

Slide 82 text

@[email protected] / @kkuchta Remote Objects Remote Object Everywhere local.rb remote.rb remote = DRbObject .new_with_uri('druby://localhost:5555') some_string = remote .make_new(String, "123")

Slide 83

Slide 83 text

@[email protected] / @kkuchta Remote Objects Remote Object Everywhere local.rb remote.rb remote = DRbObject .new_with_uri('druby://localhost:5555') some_string = remote .make_new(String, "123") some_hash = remote .make_new(Hash)

Slide 84

Slide 84 text

@[email protected] / @kkuchta Remote Objects Remote Object Everywhere local.rb remote.rb remote = DRbObject .new_with_uri('druby://localhost:5555') some_string = remote .make_new(String, "123") some_hash = remote .make_new(Hash) some_other = remote .make_new(Other, 'foo', 3)

Slide 85

Slide 85 text

@[email protected] / @kkuchta Magic New what could go wrong? local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass.new(*rest, **kwargs, &block).extend(DRb::DRb Undumped) end end some_string = String.new("foo")

Slide 86

Slide 86 text

@[email protected] / @kkuchta Magic New what could go wrong? local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass.new(*rest, **kwargs, &block).extend(DRb::DRb Undumped) end end some_string = String.new("foo") $r = DRbObject.new_with_uri( 'druby://localhost:5555') class Object def self.new(*args, **kwargs, &block) $r.remote_new( self, *args, **kwargs, &block) end end

Slide 87

Slide 87 text

@[email protected] / @kkuchta Magic New what could go wrong? local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass.new(*rest, **kwargs, &block).extend(DRb::DRb Undumped) end end some_string = String.new("foo") $r = DRbObject.new_with_uri( 'druby://localhost:5555') class Object def self.new(*args, **kwargs, &block) $r.remote_new( self, *args, **kwargs, &block) end end

Slide 88

Slide 88 text

@[email protected] / @kkuchta Magic New what could go wrong? local.rb remote.rb class RemoteNewer def make_new(klass, *rest, **kwargs, &block) obj = klass.new(*rest, **kwargs, &block).extend(DRb::DRb Undumped) end end some_string = String.new("foo") $r = DRbObject.new_with_uri( 'druby://localhost:5555') class Object def self.new(*args, **kwargs, &block) $r.remote_new( self, *args, **kwargs, &block) end end

Slide 89

Slide 89 text

@[email protected] / @kkuchta Magic New what could go wrong? local.rb remote.rb class Object def self.new(*args, **kwargs, &block) contains_recursion = caller.any? { _1 =~ /(drb\/drb)/ } end end end

Slide 90

Slide 90 text

@[email protected] / @kkuchta Magic New what could go wrong? local.rb remote.rb class Object @@old_new = method(:new) def self.new(*args, **kwargs, &block) contains_recursion = caller.any? { _1 =~ /(drb\/drb)/ } end end end

Slide 91

Slide 91 text

@[email protected] / @kkuchta Magic New what could go wrong? local.rb remote.rb class Object @@old_new = method(:new) def self.new(*args, **kwargs, &block) contains_recursion = caller.any? { _1 =~ /(drb\/drb)/ } if contains_recursion @@old_new.unbind.bind(self)[*args, **kwargs, &block] end end end

Slide 92

Slide 92 text

@[email protected] / @kkuchta Magic New what could go wrong? local.rb remote.rb class Object @@old_new = method(:new) def self.new(*args, **kwargs, &block) contains_recursion = caller.any? { _1 =~ /(drb\/drb)/ } if contains_recursion @@old_new.unbind.bind(self)[*args, **kwargs, &block] else $r.make_new(self, *args, **kwargs, &block) end end end

Slide 93

Slide 93 text

@[email protected] / @kkuchta Magic New it works! local.rb remote.rb some_string = String.new("foo") some_string.to_i arr = Array.new([1,2,3]) sum = arr.sum

Slide 94

Slide 94 text

@[email protected] / @kkuchta Magic New it works! local.rb remote.rb $ remote.rb remote: make_new remote: to_i remote: make_new remote: sum some_string = String.new("foo") some_string.to_i arr = Array.new([1,2,3]) sum = arr.sum

Slide 95

Slide 95 text

@[email protected] / @kkuchta Microservices friggin' procs local.rb remote.rb

Slide 96

Slide 96 text

@[email protected] / @kkuchta Microservices friggin' procs local.rb remote.rb arr = Array.new([1,2,3])

Slide 97

Slide 97 text

@[email protected] / @kkuchta Microservices friggin' procs local.rb remote.rb arr = Array.new([1,2,3]) sum = arr.sum

Slide 98

Slide 98 text

@[email protected] / @kkuchta Microservices friggin' procs local.rb remote.rb arr = Array.new([1,2,3]) sum = arr.sum arr.include?(2)

Slide 99

Slide 99 text

@[email protected] / @kkuchta Microservices friggin' procs local.rb remote.rb arr = Array.new([1,2,3]) sum = arr.sum arr.include?(2) arr.join("foo")

Slide 100

Slide 100 text

@[email protected] / @kkuchta Microservices friggin' procs local.rb remote.rb arr = Array.new([1,2,3]) sum = arr.sum arr.include?(2) arr.join("foo") arr.each { |i| puts i }

Slide 101

Slide 101 text

@[email protected] / @kkuchta Microservices friggin' procs local.rb remote.rb arr = Array.new([1,2,3]) sum = arr.sum arr.include?(2) arr.join("foo") arr.each { |i| puts i }

Slide 102

Slide 102 text

@[email protected] / @kkuchta Microservices friggin' procs local.rb remote.rb arr = Array.new([1,2,3]) sum = arr.sum arr.include?(2) arr.join("foo") arr.each { |i| puts i }

Slide 103

Slide 103 text

@[email protected] / @kkuchta Microservices friggin' procs

Slide 104

Slide 104 text

@[email protected] / @kkuchta Microservices friggin' procs some_remote_object.foo(arg1)

Slide 105

Slide 105 text

@[email protected] / @kkuchta Microservices friggin' procs some_remote_object.foo(arg1) # Under the hood: Marshal.dump(arg1)

Slide 106

Slide 106 text

@[email protected] / @kkuchta Microservices friggin' procs some_remote_object.foo(arg1) # Under the hood: Marshal.dump(arg1) some_remote_object.foo { |x| x + 1 }

Slide 107

Slide 107 text

@[email protected] / @kkuchta Microservices friggin' procs some_remote_object.foo(arg1) # Under the hood: Marshal.dump(arg1) some_remote_object.foo { |x| x + 1 } # Under the hood: Marshal.dump(proc { |x| x + 1 })

Slide 108

Slide 108 text

@[email protected] / @kkuchta Microservices friggin' procs > dumped = Marshal.dump({a: 1})

Slide 109

Slide 109 text

@[email protected] / @kkuchta Microservices friggin' procs > dumped = Marshal.dump({a: 1}) => "\x04\b{\x06:\x06ai\x06"

Slide 110

Slide 110 text

@[email protected] / @kkuchta Microservices friggin' procs > dumped = Marshal.dump({a: 1}) => "\x04\b{\x06:\x06ai\x06" > Marshal.load(dumped)

Slide 111

Slide 111 text

@[email protected] / @kkuchta Microservices friggin' procs > dumped = Marshal.dump({a: 1}) => "\x04\b{\x06:\x06ai\x06" > Marshal.load(dumped) => {:a=>1}

Slide 112

Slide 112 text

@[email protected] / @kkuchta Microservices friggin' procs

Slide 113

Slide 113 text

@[email protected] / @kkuchta Microservices friggin' procs Marshal.dump(proc { |x| x + 1 })

Slide 114

Slide 114 text

@[email protected] / @kkuchta Microservices friggin' procs Marshal.dump(proc { |x| x + 1 }) # TypeError: no _dump_data is # defined for class Proc

Slide 115

Slide 115 text

@[email protected] / @kkuchta Microservices friggin' procs y = 3 Marshal.dump(proc { |x| x + y }) # TypeError: no _dump_data is # defined for class Proc

Slide 116

Slide 116 text

@[email protected] / @kkuchta Microservices friggin' procs class Proc end

Slide 117

Slide 117 text

@[email protected] / @kkuchta def _dump(depth) Microservices friggin' procs class Proc end

Slide 118

Slide 118 text

@[email protected] / @kkuchta def _dump(depth) serialize_block(&self) end Microservices friggin' procs class Proc end

Slide 119

Slide 119 text

@[email protected] / @kkuchta def _dump(depth) serialize_block(&self) end Microservices friggin' procs class Proc end "{ |x| x + 1 }"

Slide 120

Slide 120 text

@[email protected] / @kkuchta def _dump(depth) serialize_block(&self) end def self._load(a_proc_string) Microservices friggin' procs class Proc end "{ |x| x + 1 }"

Slide 121

Slide 121 text

@[email protected] / @kkuchta def _dump(depth) serialize_block(&self) end def self._load(a_proc_string) Microservices friggin' procs class Proc end "{ |x| x + 1 }"

Slide 122

Slide 122 text

@[email protected] / @kkuchta def _dump(depth) serialize_block(&self) end def self._load(a_proc_string) eval('proc ' + a_proc_string) end Microservices friggin' procs class Proc end "{ |x| x + 1 }"

Slide 123

Slide 123 text

@[email protected] / @kkuchta def _dump(depth) serialize_block(&self) end def self._load(a_proc_string) eval('proc ' + a_proc_string) end Microservices friggin' procs class Proc end "{ |x| x + 1 }" eval "proc { |x| x + 1 }"

Slide 124

Slide 124 text

@[email protected] / @kkuchta Microservices friggin' procs 1. Find the source of a block

Slide 125

Slide 125 text

@[email protected] / @kkuchta Microservices friggin' procs 1. Find the source of a block some_proc = proc do |x| x + 1 end

Slide 126

Slide 126 text

@[email protected] / @kkuchta Microservices friggin' procs 1. Find the source of a block some_proc = proc do |x| x + 1 end some_proc.binding.source_location

Slide 127

Slide 127 text

@[email protected] / @kkuchta Microservices friggin' procs 1. Find the source of a block some_proc = proc do |x| x + 1 end some_proc.binding.source_location # ["some_filename.rb", 1]

Slide 128

Slide 128 text

@[email protected] / @kkuchta Microservices friggin' procs 1. Find the source of a block

Slide 129

Slide 129 text

@[email protected] / @kkuchta Microservices friggin' procs 1. Find the source of a block require 'method_source'

Slide 130

Slide 130 text

@[email protected] / @kkuchta Microservices friggin' procs 1. Find the source of a block require 'method_source' some_proc = proc do |x| x + 1 end

Slide 131

Slide 131 text

@[email protected] / @kkuchta Microservices friggin' procs 1. Find the source of a block require 'method_source' some_proc = proc do |x| x + 1 end puts some_proc.source # "some_proc = proc do |x| # x + 1 # end"

Slide 132

Slide 132 text

@[email protected] / @kkuchta Microservices friggin' procs 2. Parse out the actual block with SyntaxTree class BlockFinder < SyntaxTree::Visitor attr_reader :first_block visit_method def visit_do_block(node) @first_block ||= node end visit_method def visit_brace_block(node) @first_block ||= node end end def serialize_block(&block) source = block.source root = SyntaxTree.parse(source) visitor = BlockFinder.new visitor.visit(root) block_node = visitor.first_block formatter = SyntaxTree::Formatter.new(source, [], 80) formatter.instance_variable_set(:@stack, [proc {SyntaxTree::Program.new(statements: [], location: nil)}]) formatter.format(block_node) formatter.flush formatter.output.join end

Slide 133

Slide 133 text

@[email protected] / @kkuchta Microservices friggin' procs 2. Parse out the actual block with the SyntaxTree gem "some_proc = proc { |x| x + 1 }"

Slide 134

Slide 134 text

@[email protected] / @kkuchta Microservices friggin' procs 2. Parse out the actual block with the SyntaxTree gem = some_proc proc proc() {} |x| + x 1 "some_proc = proc { |x| x + 1 }"

Slide 135

Slide 135 text

@[email protected] / @kkuchta Microservices friggin' procs 2. Parse out the actual block with the SyntaxTree gem = some_proc proc proc() {} |x| + x 1 "some_proc = proc { |x| x + 1 }"

Slide 136

Slide 136 text

@[email protected] / @kkuchta Microservices friggin' procs 2. Parse out the actual block with the SyntaxTree gem = some_proc proc proc() {} |x| + x 1 "some_proc = proc { |x| x + 1 }"

Slide 137

Slide 137 text

@[email protected] / @kkuchta Microservices friggin' procs 2. Parse out the actual block with the SyntaxTree gem = some_proc proc proc() {} |x| + x 1 "some_proc = proc { |x| x + 1 }"

Slide 138

Slide 138 text

@[email protected] / @kkuchta Microservices friggin' procs 2. Parse out the actual block with the SyntaxTree gem = some_proc proc proc() {} |x| + x 1 "some_proc = proc { |x| x + 1 }"

Slide 139

Slide 139 text

@[email protected] / @kkuchta Microservices friggin' procs 2. Parse out the actual block with the SyntaxTree gem = some_proc proc proc() {} |x| + x 1 "some_proc = proc { |x| x + 1 }"

Slide 140

Slide 140 text

@[email protected] / @kkuchta Microservices friggin' procs 2. Parse out the actual block with the SyntaxTree gem = some_proc proc proc() {} |x| + x 1 "some_proc = proc { |x| x + 1 }"

Slide 141

Slide 141 text

@[email protected] / @kkuchta Microservices friggin' procs 2. Parse out the actual block with the SyntaxTree gem = some_proc proc proc() {} |x| + x 1 "some_proc = proc { |x| x + 1 }" "{ |x| x + 1 }"

Slide 142

Slide 142 text

@[email protected] / @kkuchta Microservices friggin' procs class Proc def _dump(depth) serialize_block(&self) end def self._load(a_proc_string) eval('proc ' + a_proc_string) end end

Slide 143

Slide 143 text

@[email protected] / @kkuchta Microservices friggin' procs dumped = Marshal.dump(proc { |x| x + 1 }) class Proc def _dump(depth) serialize_block(&self) end def self._load(a_proc_string) eval('proc ' + a_proc_string) end end

Slide 144

Slide 144 text

@[email protected] / @kkuchta Microservices friggin' procs dumped = Marshal.dump(proc { |x| x + 1 }) # "\x04\bIu:\tProc\x13 { |x| x + 1 }\x06:\x06ET" class Proc def _dump(depth) serialize_block(&self) end def self._load(a_proc_string) eval('proc ' + a_proc_string) end end

Slide 145

Slide 145 text

@[email protected] / @kkuchta Microservices friggin' procs dumped = Marshal.dump(proc { |x| x + 1 }) # "\x04\bIu:\tProc\x13 { |x| x + 1 }\x06:\x06ET" reloaded_proc = Marshal.load(dumped) class Proc def _dump(depth) serialize_block(&self) end def self._load(a_proc_string) eval('proc ' + a_proc_string) end end

Slide 146

Slide 146 text

@[email protected] / @kkuchta Microservices friggin' procs dumped = Marshal.dump(proc { |x| x + 1 }) # "\x04\bIu:\tProc\x13 { |x| x + 1 }\x06:\x06ET" reloaded_proc = Marshal.load(dumped) puts reloaded_proc[ 3 ] # prints 4! class Proc def _dump(depth) serialize_block(&self) end def self._load(a_proc_string) eval('proc ' + a_proc_string) end end

Slide 147

Slide 147 text

@[email protected] / @kkuchta Microservices friggin' procs local.rb remote.rb arr = Array.new([1,2,3]) arr.each { |i| puts i }

Slide 148

Slide 148 text

@[email protected] / @kkuchta Microservices friggin' procs local.rb remote.rb $ remote.rb remote: make_new 1 2 3 remote: each arr = Array.new([1,2,3]) arr.each { |i| puts i }

Slide 149

Slide 149 text

@[email protected] / @kkuchta Microservices literally the worst arr = [1,2,3] str = "foo" hash = {a: 1, b: 2}

Slide 150

Slide 150 text

@[email protected] / @kkuchta Microservices literally the worst class Array def self.new puts "new called" end end

Slide 151

Slide 151 text

@[email protected] / @kkuchta Microservices literally the worst class Array def self.new puts "new called" end end Array.new # "new called"

Slide 152

Slide 152 text

@[email protected] / @kkuchta Microservices literally the worst class Array def self.new puts "new called" end end Array.new # "new called" [1,2,3] # nothing

Slide 153

Slide 153 text

@[email protected] / @kkuchta Microservices literally the worst x = [1,2,3] x = Array.new([1,2,3])

Slide 154

Slide 154 text

@[email protected] / @kkuchta Microservices literally the worst DATA

Slide 155

Slide 155 text

@[email protected] / @kkuchta Microservices literally the worst DATA

Slide 156

Slide 156 text

@[email protected] / @kkuchta Microservices literally the worst puts "hi" puts DATA.read()

Slide 157

Slide 157 text

@[email protected] / @kkuchta Microservices literally the worst puts "hi" puts DATA.read() __END__

Slide 158

Slide 158 text

@[email protected] / @kkuchta Microservices literally the worst puts "hi" puts DATA.read() __END__ hello there, world, how are you?

Slide 159

Slide 159 text

@[email protected] / @kkuchta Microservices literally the worst puts "hi" puts DATA.read() __END__ hello there, world, how are you? # prints: "hello there, world, how are you?"

Slide 160

Slide 160 text

@[email protected] / @kkuchta Microservices literally the worst puts "hi" puts DATA.read() __END__ arr = [1,2,3]

Slide 161

Slide 161 text

@[email protected] / @kkuchta Microservices literally the worst puts "hi" eval(DATA.read()) __END__ arr = [1,2,3]

Slide 162

Slide 162 text

@[email protected] / @kkuchta Microservices literally the worst eval( DATA.read .gsub(/\[(.*)\]/, 'Array.new([\1])') ) __END__ arr = [1,2,3] # converts to Array.new([1,2,3])

Slide 163

Slide 163 text

@[email protected] / @kkuchta Microservices literally the worst eval(DATA.read .gsub(/\[(.*)\]/, 'Array.new([\1])') .gsub(/{([^|]+:[^|]+)}/, 'Hash.new.merge!({\1})') .gsub(/"(.*)"/, 'String.new("\1")')) __END__ arr = [1,2,3] hash = {a: 1, b: 2} str = "whatever"

Slide 164

Slide 164 text

@[email protected] / @kkuchta Peak Architecture less distributed

Slide 165

Slide 165 text

@[email protected] / @kkuchta Peak Architecture more distributes

Slide 166

Slide 166 text

@[email protected] / @kkuchta Peak Architecture more distributes

Slide 167

Slide 167 text

@[email protected] / @kkuchta Peak Architecture more distributed def handler(event:, context:) x = event['x'] return x * 2 end

Slide 168

Slide 168 text

@[email protected] / @kkuchta Peak Architecture more distributed def handler(event:, context:) # ... end

Slide 169

Slide 169 text

@[email protected] / @kkuchta Peak Architecture more distributed def lambda_handler(event:, context:) DRb.start_service( "druby://localhost:5555", RemoteNewer.new ) DRb.thread.join end

Slide 170

Slide 170 text

@[email protected] / @kkuchta Peak Architecture more distributed def lambda_handler(event:, context:) DRb.start_service( "druby://localhost:5555", RemoteNewer.new ) DRb.thread.join end

Slide 171

Slide 171 text

@[email protected] / @kkuchta Peak Architecture more distributed def lambda_handler(event:, context:) DRb.start_service( "druby://localhost:5555", RemoteNewer.new ) DRb.thread.join end

Slide 172

Slide 172 text

@[email protected] / @kkuchta Peak Architecture more distributed local.rb remote.rb class Object # ... def self.remote_new(*args, **kwargs, &block) end end

Slide 173

Slide 173 text

@[email protected] / @kkuchta Peak Architecture more distributed local.rb remote.rb class Object # ... def self.remote_new(*args, **kwargs, &block) end end lambda_hostname = start_lambda()

Slide 174

Slide 174 text

@[email protected] / @kkuchta Peak Architecture more distributed local.rb remote.rb class Object # ... def self.remote_new(*args, **kwargs, &block) end end lambda_hostname = start_lambda() sleep 3

Slide 175

Slide 175 text

@[email protected] / @kkuchta Peak Architecture more distributed local.rb remote.rb class Object # ... def self.remote_new(*args, **kwargs, &block) end end lambda_hostname = start_lambda() sleep 3 uri = "druby://#{lambda_hostname}:5555"

Slide 176

Slide 176 text

@[email protected] / @kkuchta Peak Architecture more distributed local.rb remote.rb class Object # ... def self.remote_new(*args, **kwargs, &block) end end lambda_hostname = start_lambda() sleep 3 uri = "druby://#{lambda_hostname}:5555" remote_newer = DRbObject.new_with_uri(uri)

Slide 177

Slide 177 text

@[email protected] / @kkuchta Peak Architecture more distributed local.rb remote.rb class Object # ... def self.remote_new(*args, **kwargs, &block) end end lambda_hostname = start_lambda() sleep 3 uri = "druby://#{lambda_hostname}:5555" remote_newer = DRbObject.new_with_uri(uri) new_obj = remote_newer.make_new( self, *args, **kwargs, &block)

Slide 178

Slide 178 text

@[email protected] / @kkuchta Peak Architecture more distributed local.rb remote.rb class Object # ... def self.remote_new(*args, **kwargs, &block) end end lambda_hostname = start_lambda() sleep 3 uri = "druby://#{lambda_hostname}:5555" remote_newer = DRbObject.new_with_uri(uri) new_obj = remote_newer.make_new( self, *args, **kwargs, &block) new_obj.instance_variable_set(:@uri, uri)

Slide 179

Slide 179 text

@[email protected] / @kkuchta Peak Architecture more distributed local.rb remote.rb class Object # ... def self.remote_new(*args, **kwargs, &block) end end lambda_hostname = start_lambda() sleep 3 uri = "druby://#{lambda_hostname}:5555" remote_newer = DRbObject.new_with_uri(uri) new_obj = remote_newer.make_new( self, *args, **kwargs, &block) new_obj.instance_variable_set(:@uri, uri) new_obj

Slide 180

Slide 180 text

@[email protected] / @kkuchta Peak Architecture more distributes

Slide 181

Slide 181 text

@[email protected] / @kkuchta Peak Architecture more distributes

Slide 182

Slide 182 text

@[email protected] / @kkuchta Microservices Every goddamn object local.rb remote.rb class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 183

Slide 183 text

@[email protected] / @kkuchta Microservices Every goddamn object 1. Preprocess all literals with regexes into .new calls eval(DATA.read .gsub( /\[(.*)\]/, 'Array.new([\1])') .gsub( /{([^|]+:[^|]+)}/, 'Hash.new.merge!({\1})') .gsub( /"(.*)"/, 'String.new("\1")')) __END__ arr = [1,2,3] hash = {a: 1, b: 2} str = "whatever"

Slide 184

Slide 184 text

@[email protected] / @kkuchta Microservices Every goddamn object 1. Preprocess all literals with regexes into .new calls 2. Overide Object.new 3. Inspect the call stack to prevent stack over f lows class Object @@old_new = method(:new) def self.new(*args, **kwargs, &block) contains_recursion = caller .any? { _1 =~ /(drb\/drb)/ } if contains_recursion @@old_new.unbind .bind(self)[*args, **kwargs, &block] else $r.make_new(self, *args, **kwargs, &block) end end end

Slide 185

Slide 185 text

@[email protected] / @kkuchta Microservices Every goddamn object 1. Preprocess all literals with regexes into .new calls 2. Overide Object.new 3. Inspect the call stack to prevent stack over f lows 4. Use Druby to create remote proxy objects # local.rb uri = "druby://#{lambda_hostname}:5555" remote_newer = DRbObject.new_with_uri(uri) new_obj = remote_newer .make_new(self, *args, **kwargs, &block) # remote.rb DRb.start_service("druby://localhost:5555", RemoteRunner.new) DRb.thread.join

Slide 186

Slide 186 text

@[email protected] / @kkuchta Microservices Every goddamn object 1. Preprocess all literals with regexes into .new calls 2. Overide Object.new 3. Inspect the call stack to prevent stack over f lows 4. Use Druby to create remote proxy objects 5. Parse the AST from your own source to serialize procs class Proc def _dump(depth) serialize_block(&self) end def self._load(a_proc_string) eval('proc ' + a_proc_string) end end

Slide 187

Slide 187 text

@[email protected] / @kkuchta Microservices Every goddamn object 1. Preprocess all literals with regexes into .new calls 2. Overide Object.new 3. Inspect the call stack to prevent stack over f lows 4. Use Druby to create remote proxy objects 5. Parse the AST from your own source to serialize procs 6. Run the remote server in a lambda def lambda_handler(event:, context:) DRb.start_service( "druby://localhost:5555", RemoteRunner.new) DRb.thread.join end

Slide 188

Slide 188 text

@[email protected] / @kkuchta Microservices Every goddamn object 1. Preprocess all literals with regexes into .new calls 2. Overide Object.new 3. Inspect the call stack to prevent stack over f lows 4. Use Druby to create remote proxy objects 5. Parse the AST from your own source to serialize procs 6. Run the remote server in a lambda 7. MICROSERVICES! def lambda_handler(event:, context:) DRb.start_service( "druby://localhost:5555", RemoteRunner.new) DRb.thread.join end

Slide 189

Slide 189 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo local.rb remote.rb

Slide 190

Slide 190 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote local.rb remote.rb

Slide 191

Slide 191 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote local.rb remote.rb

Slide 192

Slide 192 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote local.rb remote.rb

Slide 193

Slide 193 text

@[email protected] / @kkuchta Microservices Every goddamn object class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote local.rb remote.rb

Slide 194

Slide 194 text

@[email protected] / @kkuchta # local.rb: arr = [1,2,3] str = "whatever" puts arr.map { |x| x * 2} str.each_char { |c| puts c }

Slide 195

Slide 195 text

@[email protected] / @kkuchta $ time ruby local.rb > /dev/null 0.98s user 0.23s system 12% cpu 9.803 total # local.rb: arr = [1,2,3] str = "whatever" puts arr.map { |x| x * 2} str.each_char { |c| puts c }

Slide 196

Slide 196 text

@[email protected] / @kkuchta Microservices Every goddamn object

Slide 197

Slide 197 text

@[email protected] / @kkuchta Microservices Every goddamn object

Slide 198

Slide 198 text

@[email protected] / @kkuchta Microservices Every goddamn object

Slide 199

Slide 199 text

@[email protected] / @kkuchta slower, more expensive, complex

Slide 200

Slide 200 text

@[email protected] / @kkuchta Microservices! slower, more expensive, complex

Slide 201

Slide 201 text

@[email protected] / @kkuchta Microservices Every goddamn object Q&A class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 202

Slide 202 text

@[email protected] / @kkuchta Microservices Every goddamn object FAQ class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 203

Slide 203 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Should I use this in production? FAQ class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 204

Slide 204 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Should I use this in production? A: De f initely! FAQ class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 205

Slide 205 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Should I use this in production? A: De f initely! FAQ Q: What's a good use for druby for? class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 206

Slide 206 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Should I use this in production? A: De f initely! FAQ Q: What's a good use for druby for? A: Smaller, internal projects class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 207

Slide 207 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Where can I see this code in more detail? Q: Should I use this in production? A: De f initely! FAQ Q: What's a good use for druby for? A: Smaller, internal projects class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 208

Slide 208 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Where can I see this code in more detail? A: github.com/kkuchta/druby Q: Should I use this in production? A: De f initely! FAQ Q: What's a good use for druby for? A: Smaller, internal projects class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 209

Slide 209 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Who's responsible for this mess Q: Where can I see this code in more detail? A: github.com/kkuchta/druby Q: Should I use this in production? A: De f initely! FAQ Q: What's a good use for druby for? A: Smaller, internal projects class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 210

Slide 210 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Who's responsible for this mess A: Kevin Kuchta, @kkuchta, kevinkuchta.com Q: Where can I see this code in more detail? A: github.com/kkuchta/druby Q: Should I use this in production? A: De f initely! FAQ Q: What's a good use for druby for? A: Smaller, internal projects class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 211

Slide 211 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Who's responsible for this mess A: Kevin Kuchta, @kkuchta, kevinkuchta.com Q: Where can I see this code in more detail? A: github.com/kkuchta/druby Q: Should I use this in production? A: De f initely! Q: I have a real question FAQ Q: What's a good use for druby for? A: Smaller, internal projects class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 212

Slide 212 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Who's responsible for this mess A: Kevin Kuchta, @kkuchta, kevinkuchta.com Q: Where can I see this code in more detail? A: github.com/kkuchta/druby Q: Should I use this in production? A: De f initely! Q: I have a real question A: Right here! FAQ Q: What's a good use for druby for? A: Smaller, internal projects class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 213

Slide 213 text

@[email protected] / @kkuchta Microservices Every goddamn object Q: Who's responsible for this mess A: Kevin Kuchta, @kkuchta, kevinkuchta.com Q: Where can I see this code in more detail? A: github.com/kkuchta/druby Q: Should I use this in production? A: De f initely! Q: I have a real question A: Right here! Q: Who's paying you to do this nonsense FAQ Q: What's a good use for druby for? A: Smaller, internal projects class SomeClass def foo puts [1,2,3].map { puts "hi" } end end obj = SomeClass.new obj.foo Remote Remote Remote Remote

Slide 214

Slide 214 text

@[email protected] / @kkuchta DaybreakHealth.com [email protected] https://daybreakhealth.applytojob.com/apply/

Slide 215

Slide 215 text

@[email protected] / @kkuchta Thank You DaybreakHealth.com [email protected] https://daybreakhealth.applytojob.com/apply/

Slide 216

Slide 216 text

@[email protected] / @kkuchta Credits - Poorly Drawn Lines comic - https://poorlydrawnlines.com/comic/an-idea/ - https://creativecommons.org/licenses/by-nc/3.0/