-
-
Save bogdanRada/2346c0f48a6bb8c089bc to your computer and use it in GitHub Desktop.
LolConcurrency::Actor Make Your own Celluloid
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
require 'forwardable' | |
require 'thread' | |
require 'monitor' | |
module LolConcurrency | |
module Actor | |
Context = Struct.new(:method, :args, :block) | |
Async = Struct.new(:instance, :mailbox) do | |
extend Forwardable | |
def_delegator :instance, :respond_to? | |
private :instance | |
private :mailbox | |
def initialize(instance) | |
super(instance, Queue.new) | |
run! | |
end | |
def method_missing(method, *args, &block) | |
mailbox << Context.new(method, args, block) | |
nil | |
end | |
private | |
def run! | |
Thread.new do | |
loop do | |
ctx = mailbox.pop | |
instance.public_send(ctx.method, *ctx.args, &ctx.block) | |
end | |
end | |
end | |
end | |
def async | |
@async ||= begin | |
synchronize do | |
@async ||= Async.new(self) | |
end | |
end | |
end | |
def self.included(klass) | |
unless klass < MonitorMixin | |
klass.send(:include, MonitorMixin) | |
end | |
end | |
end | |
end |
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
require 'forwardable' | |
require 'thread' | |
require 'monitor' | |
module LolConcurrency | |
module Future | |
Future = Struct.new(:queue) do | |
include MonitorMixin | |
private :queue | |
def value | |
@value ||= begin | |
synchronize do | |
@value ||= queue.pop | |
end | |
end | |
end | |
end | |
Factory = Struct.new(:instance) do | |
extend Forwardable | |
def_delegator :instance, :respond_to? | |
private :instance | |
def method_missing(method, *args, &block) | |
queue = SizedQueue.new(1) | |
Thread.new do | |
queue << instance.public_send(method, *args, &block) | |
end | |
Future.new(queue) | |
end | |
end | |
def future | |
@future ||= begin | |
synchronize do | |
@future ||= Factory.new(self) | |
end | |
end | |
end | |
def self.included(klass) | |
unless klass < MonitorMixin | |
klass.send(:include, MonitorMixin) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment