async-proxy
An Async proxy is a wrapper around a real object that intercepts method calls and runs them in an asynchronous way.
Construction
Async proxies will be generally constructed calling .async on any object.
Behaviour
Calling any method in async proxy creates a new thread in charge of running the actual computation and control is immediately returned to the callee.
When the actual result of the method call is needed, call sync
on the returned value and this will wait (if necessary) for the thread to finish and provide the real value.
Example:
async_recommendations = user.async.recommendations # computing the recommendations is really slow!
#do other stuff
print async_recommendations.sync
Chaining
The result of a method call in an async proxy will itself be an async proxy. This allows for chained computations:
my_async_result = object.async.some_slow_method.and_another_one(with_an_argument).and_a_third_one
currency = user.async.country.currency
Each chained method is run as soon as the previous level result is available. Calling sync in any dependent value will automatically wait for all dependencies.
Dependent computations
Sometimes you want to run some code on the returned value as soon as it is available. With async proxy you do that with:
-
register_callback: run the code but do not care about the return value
async_proxy.slow_method.register_callback{|return_value| puts return_value}
-
when_ready: returns yet another async proxy that lets you recover the block’s returned value
squared = async_proxy.slow_method.when_ready{|return_value| return_value * return_value } .. squared.sync
Automatic synchronization
Some method calls automatically trigger synchronization:
-
to_s
-
inspect
-
each
This means that in most cases you can treat an async object exactly in the same way that the wrapped object. You generally don’t need to make explicit sync
calls (although you can if you want to control the exact moment the object will be “realized”)
Soft timeouts
Sometimes you are interested in a value only if it can be computed in a certain time.
async_result = async_proxy.slow_method
..
result = async_result.sync(:soft_timeout => 0.30)
Locking and thread safety
Async Proxy makes no attempt to guarantee thread safety. It can be considered as just syntactic sugar to automate the creations of threads, so if your code is not thread-safe or uses libraries that are not thread-safe mischief will happen.
Note on Patches/Pull Requests
-
Fork the project.
-
Make your feature addition or bug fix.
-
Add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
-
Send me a pull request. Bonus points for topic branches.
Copyright
Copyright © 2010 Angel Faus. See LICENSE for details.