Module: LazyData
- Defined in:
- lib/lazy_data/dict.rb,
lib/lazy_data/value.rb,
lib/lazy_data/expiry.rb,
lib/lazy_data/retries.rb,
lib/lazy_data/version.rb,
lib/lazy_data/internal_state.rb,
lib/lazy_data.rb
Overview
LazyData provides data types featuring thread-safe lazy computation.
LazyData objects are constructed with a block that can be called to compute the final value, but it is not actually called until the value is requested. Once requested, the computation takes place only once, in the first thread that requested the value. Future requests will return a cached value. Furthermore, any other threads that request the value during the initial computation will block until the first thread has completed the computation.
- Value holds a single value
- Dict holds a dictionary of values, where each key points to a separate lazy value
This implementation also provides retry and expiration features. The code was extracted from the google-cloud-env gem that originally used it.
Defined Under Namespace
Classes: Dict, InternalState, Retries, Value
Constant Summary collapse
- VERSION =
Current version of lazy_data
"0.1.0"
Class Method Summary collapse
-
.dict(retries: nil, lifetime: nil, &block) ⇒ Object
Create a LazyData::Dict.
-
.expiring_value(lifetime, value) ⇒ Object
Creates a special object that can be returned from a computation to indicate that a value expires after the given number of seconds.
-
.raise_expiring_error(lifetime, error, *args) ⇒ Object
Raise an error that, if it is the final result (i.e. retries have been exhausted), will expire after the given number of seconds.
-
.value(retries: nil, lifetime: nil, &block) ⇒ Object
Create a LazyData::Value.
Class Method Details
.dict(retries: nil, lifetime: nil, &block) ⇒ Object
Create a LazyData::Dict.
You must pass a block that will be called to compute the value the first time it is accessed. The block takes the key as an argument and should evaluate to the value for that key, or raise an exception on error. To specify a value that expires, use expiring_value. To raise an exception that expires, use raise_expiring_error.
You can optionally pass a retry manager, which controls how subsequent accesses might try calling the block again if a compute attempt fails with an exception. A retry manager should either be an instance of Retries or an object that duck types it.
94 95 96 |
# File 'lib/lazy_data.rb', line 94 def dict(retries: nil, lifetime: nil, &block) LazyData::Dict.new(retries: retries, lifetime: lifetime, &block) end |
.expiring_value(lifetime, value) ⇒ Object
Creates a special object that can be returned from a computation to indicate that a value expires after the given number of seconds. Any access after the expiration will cause a recomputation.
32 33 34 35 |
# File 'lib/lazy_data/expiry.rb', line 32 def expiring_value(lifetime, value) return value unless lifetime ExpiringValue.new(lifetime, value) end |
.raise_expiring_error(lifetime, error, *args) ⇒ Object
Raise an error that, if it is the final result (i.e. retries have been exhausted), will expire after the given number of seconds. Any access after the expiration will cause a recomputation. If retries will not have been exhausted, expiration is ignored.
The error can be specified as an exception object, a string (in which case a RuntimeError will be raised), or a class that descends from Exception (in which case an error of that type will be created, and passed any additional args given).
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/lazy_data/expiry.rb', line 53 def raise_expiring_error(lifetime, error, *args) raise error unless lifetime raise ExpiringError, lifetime if error.equal?($!) if error.is_a?(::Class) && error.ancestors.include?(::Exception) error = error.new(*args) elsif !error.is_a?(::Exception) error = ::RuntimeError.new(error.to_s) end begin raise error rescue error.class raise ExpiringError, lifetime end end |
.value(retries: nil, lifetime: nil, &block) ⇒ Object
Create a LazyData::Value.
You must pass a block that will be called to compute the value the first time it is accessed. The block should evaluate to the desired value, or raise an exception on error. To specify a value that expires, use expiring_value. To raise an exception that expires, use raise_expiring_error.
You can optionally pass a retry manager, which controls how subsequent accesses might try calling the block again if a compute attempt fails with an exception. A retry manager should either be an instance of Retries or an object that duck types it.
66 67 68 |
# File 'lib/lazy_data.rb', line 66 def value(retries: nil, lifetime: nil, &block) LazyData::Value.new(retries: retries, lifetime: lifetime, &block) end |