LazyMethods¶ ↑
This adds the ability to declare lazy loading or asynchronous methods.
Lazy Loading Methods¶ ↑
Lazy methods will return immediately with a proxy object. The proxy object will look and act just like the result from calling the method. However, the original method will only be called when a method is invoked on the proxy object.
This pattern works great with caching. You can have your business logic invoke lazy methods and your view logic sitting behind a cache. If the cache is hit, you won’t actually end up invoking any of your business logic.
To define a lazy method, simply include the LazyMethods module in your class definition and then call define_lazy_methods
or define_lazy_class_methods
with the names of one or more methods defined for your class. This will create lazy versions of the methods with the names prefixed with lazy_
.
Example¶ ↑
class MyModel include LazyMethods define_lazy_methods :calculate_value define_lazy_class_methods :find end object = MyModel.lazy_find # The find method will not be called yet object.to_s # The find will will be called here value = object.lazy_calculate_value # The calculate_value method will not be called yet sum = value + 1 # The calculate_value method will be called here
Asynchronous Methods¶ ↑
Asynchronouse methods are similar to lazy methods. The method call will return immediately with a proxy object. The difference is that the original method will be invoked immediately in a separate thread. When a method is called on the proxy object, the thread will block until the result is returned. This can be useful if you have methods that wait on IO like web service calls.
Example¶ ↑
class MyModel include LazyMethods define_async_methods :get_related_info define_async_class_methods :find end objects = MyModel.async_find # The find method will be called in a new thread objects.size # Execution will wait until the find thread has finished objects.each do |obj| obj.async_get_related_info # A new thread will be started for each object to call get_related_info end
Usage Notes¶ ↑
Since lazy methods are not invoked at the time when you call them, there is a chance for the state of you application to change between the time when you invoke a method and when it is actually called.
# In this example, the value of object.value will be 2 when the do_something method is called. object.value = 1 value = object.lazy_do_somthing object.value = 2 value.to_s
Similarly, all asynchronous methods must make sure they are thread safe.
Exception handling can also be tricky since exceptions will not be immediately thrown.
value = nil begin value = object.lazy_do_something rescue => e # Exceptions thrown by do_something won't be caught here. end value.to_s # Exceptions thrown by do_something will be thrown here instead.
Upgrade Notes¶ ↑
In version 1.x of this gem, lazy methods were automatically available for every method on every object. You must now define which methods should be defined as lazy methods. This change was made so that the code is less intrusive and the lazy method invocations are slightly faster.
In addition, version 2.x of this gem includes the functionality of the async_methods 1.x gem. That gem is no longer being maintained.