Created
August 11, 2023 10:37
-
-
Save iftheshoefritz/8850919da3c07e2fede55c5b8c9ac421 to your computer and use it in GitHub Desktop.
Starting point for parallel Ruby conversations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
# problem code from Graceful.dev: https://graceful.dev/courses/tapastry/modules/2019/topic/full-utilization/ | |
$tick = 0 | |
def work(seconds) | |
$tick += seconds | |
end | |
def log(message) | |
puts "%3d: %s" % [$tick, message] | |
end | |
class Smore | |
attr_accessor :started_at, :finished_at | |
attr_reader :camper | |
def initialize(camper) | |
@camper = camper | |
@started_at = started_at | |
@finished_at = finished_at | |
end | |
def wait | |
finished_at - started_at | |
end | |
def to_s | |
@camper | |
end | |
end | |
class MarshmallowWrangler | |
def start(smore) | |
fail "I'm busy!" unless @ready_at.to_i <= $tick | |
@ready_at = $tick + 20 | |
smore.started_at = $tick | |
end | |
def finish(smore) | |
log("A marshmallow is ready for #{smore.camper}") | |
end | |
end | |
class Toaster | |
def start(smore) | |
fail "I'm busy!" unless @ready_at.to_i <= $tick | |
@ready_at = $tick + 60 | |
end | |
def finish(smore) | |
log("A marshmallow is toasty warm for #{smore}") | |
end | |
end | |
class Assembler | |
def start(smore) | |
fail "I'm busy!" unless @ready_at.to_i <= $tick | |
@ready_at = $tick + 30 | |
end | |
def finish(smore) | |
smore.finished_at = $tick | |
log("Your s'more is ready, #{smore}!") | |
end | |
end | |
wrangler = MarshmallowWrangler.new | |
toaster = Toaster.new | |
assembler = Assembler.new | |
smore_orders = ["Kashti", "Ebba", "Ylva"] | |
smores = smore_orders.map { |camper| Smore.new(camper) } | |
puts "*"*50 + "non-ractor version start" | |
wrangler.start(smores[0]) | |
work(20) | |
wrangler.finish(smores[0]) | |
puts "*"*50 + "non-ractor version end" | |
# wrangler.start(smores[1]) | |
# toaster.start(smores[0]) | |
# work(20) | |
# wrangler.finish(smores[1]) | |
# wrangler.start(smores[2]) | |
# work(20) | |
# wrangler.finish(smores[2]) | |
# work(20) # 80 | |
# toaster.finish(smores[0]) | |
# toaster.start(smores[1]) | |
# assembler.start(smores[0]) | |
# work(30) # 110 | |
# assembler.finish(smores[0]) | |
# work(30) # 140 | |
# toaster.finish(smores[1]) | |
# toaster.start(smores[2]) | |
# assembler.start(smores[1]) | |
# work(30) # 170 | |
# assembler.finish(smores[1]) | |
# work(30) # 200 | |
# toaster.finish(smores[2]) | |
# assembler.start(smores[2]) | |
# work(30) # 230 | |
# assembler.finish(smores[2]) | |
# example of Ractors from https://blog.appsignal.com/2022/08/24/an-introduction-to-ractors-in-ruby.html | |
# How do Ractors help? how can we call wrangler from a Ractor? | |
#supermarket = Ractor.new do | |
# loop do | |
# order = Ractor.receive | |
# puts "The supermarket is preparing #{order}" | |
# Ractor.yield "This is #{order}" | |
# end | |
#end | |
# | |
#customers = 5.times.map{ |i| | |
# .pass supermarket ractor and index to the customer ractor | |
# Ractor.new(supermarket, i) do |supermarket, i| | |
# supermarket.send("a pack of sugar for customer #{i}") | |
# fulfilled_order = supermarket.take | |
# puts "#{fulfilled_order} received by customer #{i}" | |
# end | |
#} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment