Skip to content

Gem that adds asynchronous method calls for all methods on every object to aid in throughput on I/O bound processes. This is intended to improve throughput on I/O bound processes like making several HTTP calls in row.

License

bdurand/async_methods

Repository files navigation

AsyncMethods

Note: This gem is no longer being maintained. The functionality has been rolled into the lazy_methods gem (rubygems.org/gems/lazy_methods).

For those times you application is bound on I/O…

Enter AsyncMethods.

This plugin adds a virtual asynchronous version of every method on every class. Asynchronouse methods have the same name as the original method name but prefixed with “async_”. An asynchronous method will invoke to original method in a new thread and immediately return a proxy object that looks and acts just like the result from calling the actual method. When this proxy object is accessed for the first time, it will only then wait for the thread executing the method to finish.

If you add fragment caching to your views and the cache returns a value and bypasses your view code, the method will never be invoked. Thanks to the magic of Ruby the proxy object will even act like the class it is proxying in class to class and kind_of?

A simple example:

The normal way to do it:

def index
  @record_1 = MyResource.load(:first, :conditions => {:name => params[:name_1]})
  @record_2 = MyResource.load(:first, :conditions => {:name => params[:name_2]})
  @record_3 = MyResource.load(:first, :conditions => {:name => params[:name_3]})
end

If the calls to load the resource each takes an average of 0.1 seconds, loading all three will take 0.3 seconds. In a web application this can start adding up quickly, especially under a heavy load. However, by using asynchronous methods like this, all three calls will happen in parallel and they should all complete in 0.1 seconds.

def index
  @record_1 = MyResource.async_load(:first, :conditions => {:name => params[:name_1]})
  @record_2 = MyResource.async_load(:first, :conditions => {:name => params[:name_2]})
  @record_3 = MyResource.async_load(:first, :conditions => {:name => params[:name_3]})
end

Be Careful

Because underneath it all new threads are being spawned, you must be careful to make sure that the code you are calling is thread safe. For example, the default configuration for ActiveRecord is not thread safe so loading several calls from the database at once would cause you problems. This plugin was originally written to speed up parallel loads of ActiveResource records, so that should be safe to do.

Testing

Since the proxy object looks and acts just like the real result object, all your view tests should still pass. Your controller tests should pass will little or no tweaking.

About

Gem that adds asynchronous method calls for all methods on every object to aid in throughput on I/O bound processes. This is intended to improve throughput on I/O bound processes like making several HTTP calls in row.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages