Skip to content

Instantly share code, notes, and snippets.

@bogdanRada
Forked from darkhelmet/actor.rb
Last active August 31, 2015 09:38
Show Gist options
  • Save bogdanRada/2346c0f48a6bb8c089bc to your computer and use it in GitHub Desktop.
Save bogdanRada/2346c0f48a6bb8c089bc to your computer and use it in GitHub Desktop.
LolConcurrency::Actor Make Your own Celluloid
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
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