Skip to content

Instantly share code, notes, and snippets.

@jemminger
Created July 2, 2011 14:25
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jemminger/1060484 to your computer and use it in GitHub Desktop.
Save jemminger/1060484 to your computer and use it in GitHub Desktop.
Make any Ruby method asynchronous
# from http://stackoverflow.com/questions/6499654/is-there-an-asynchronous-logging-library-for-ruby/6527134#6527134
require 'thread'
require 'singleton'
require 'delegate'
require 'monitor'
class Async
include Singleton
def initialize
@queue = Queue.new
Thread.new { loop { @queue.pop.call } }
end
def run(&blk)
@queue.push blk
end
end
class Work < Delegator
include MonitorMixin
def initialize(&work)
super work; @work, @done, @lock = work, false, new_cond
end
def calc
synchronize {
@result, @done = @work.call, true;
@lock.signal
}
end
def __getobj__
synchronize { @lock.wait_while { !@done } }
@result
end
end
Module.class.class_exec {
def async(*method_names)
method_names.each do |method_name|
original_method = instance_method(method_name)
define_method(method_name) do |*args,&blk|
work = Work.new { original_method.bind(self).call(*args,&blk) }
Async.instance.run { work.calc }
return work
end
end
end
}
require 'Logger'
class Logger
async :debug
end
log = Logger.new STDOUT
log.debug "heloo"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment