Skip to content

Instantly share code, notes, and snippets.

@sheenobu
Created November 9, 2012 23:08
Show Gist options
  • Select an option

  • Save sheenobu/4048921 to your computer and use it in GitHub Desktop.

Select an option

Save sheenobu/4048921 to your computer and use it in GitHub Desktop.
Ruby Declarative Async Experiment.
require 'eventmachine'
require 'aquarium'
class Promise
def null_method(*args)
end
def initialize
@finally = @on_success = @on_error = method(:null_method)
end
def on_success(&blk)
@on_success = blk
self
end
def on_error(&blk)
@on_error = blk
self
end
def exec(*args)
@finally.call(@on_success.call(*args),*args)
end
def finally(&blk)
@finally = blk
self
end
end
class Class
def async_for(*method_names, &block)
method_names.each do |method_name|
define_method (method_name.to_s + "_async") do |*args|
instance_exec method_name do |*ignored|
self.send(method_name.to_s,*args)
end
end
end
end
end
module AsyncMethods
def self.append_features mod
Aquarium::Aspects::Aspect.new :around, :type => mod, :calls_to => /_async/, :method_options => [:exclude_ancestor_methods] do |jp, object, *args|
promise = Promise.new
EventMachine.next_tick do
ret = jp.proceed
promise.exec(ret)
end
promise
end
end
end
module RunDecorator
def self.append_features mod
Aquarium::Aspects::Aspect.new :around, :type => mod, :methods => /run/, :method_options => [:exclude_ancestor_methods] do |jp,object,*args|
names = "#{jp.target_type.name}##{jp.method_name}"
p "Entering: #{names}: args = #{args.inspect}"
jp.proceed
p "Leaving: #{names}: args = #{args.inspect}"
end
end
end
"Entering: TestAsyncClass#run: args = [12]"
run-method 12
"Leaving: TestAsyncClass#run: args = [12]"
"Entering: TestAsyncClass#run_noargs: args = []"
run-noargs-method
"Leaving: TestAsyncClass#run_noargs: args = []"
Done
require_relative './declarative_async'
class TestAsyncClass
def run(x)
puts("run-method #{x}")
end
def run_noargs
puts("run-noargs-method")
end
include RunDecorator
end
TestAsyncClass.class_eval do
async_for :run,:run_noargs
include AsyncMethods
end
EventMachine.run do
a = TestAsyncClass.new
a.run_async(12)
.on_success do
a.run_noargs_async
.on_success do
puts("Done")
end
.on_error do
end
.finally do
EventMachine.stop
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment