Skip to content

Instantly share code, notes, and snippets.

@tompng
Last active September 21, 2020 10:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tompng/7d69710754ea3f08a65bab6afca59f3a to your computer and use it in GitHub Desktop.
Save tompng/7d69710754ea3f08a65bab6afca59f3a to your computer and use it in GitHub Desktop.
module InMainRactor
def self.pipe() = Ractor.new { loop { Ractor.yield Ractor.recv } }
REQUEST = pipe
LOCK = pipe
LOCK << :lock
RESPONSE = pipe
MAIN_RACTOR = Ractor.current
class Delegator < BasicObject
def initialize(receiver)
@receiver = receiver
end
def method_missing(method, *args, **kwargs)
lock = ::InMainRactor::LOCK.take
::InMainRactor::REQUEST << [@receiver, method, args, kwargs]
response = ::InMainRactor::RESPONSE.take
::InMainRactor::LOCK << lock
response
end
end
def self.run_main_ractor
loop do
receiver, method, args, kwargs = REQUEST.take
RESPONSE << receiver.__send__(method, *args, **kwargs)
rescue => e
RESPONSE << e
end
end
Thread.new { run_main_ractor }
module Delegatable
def in_main_ractor
if ::Ractor.current == ::InMainRactor::MAIN_RACTOR
self
else
InMainRactor::Delegator.new self
end
end
end
end
require_relative './in_main_ractor'
Module.include InMainRactor::Delegatable
class Foo
def self.bar
@@x ||= 0
@@x += 1
end
end
10.times do
Ractor.new do
100.times { Foo.in_main_ractor.bar }
end
p :done
end
sleep 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment