Transaction
pub struct Transaction { /* private fields */ }A cache transaction initiated by Transaction::lookup().
Transactions coordinate between concurrent actions on the same cache key, incorporating concepts of request collapsing and revalidation, though at a lower level that does not automatically interpret HTTP semantics.
Request collapsing
If there are multiple concurrent calls to Transaction::lookup() for the same item and that
item is not present, just one of the callers will be instructed to insert the item into the
cache as part of the transaction. The other callers will block until the metadata for the item
has been inserted, and can then begin streaming its contents out of the cache at the same time
that the inserting caller streams them into the cache. To avoid blocking while waiting for the
object to be provided, clients can use TransactionLookupBuilder::execute_async().
Revalidation
Similarly, if an item is usable but stale, and multiple callers attempt a
Transaction::lookup() concurrently, they will all be given access to the stale item, but
only one will be designated to perform an asynchronous update (or insertion) to freshen the item
in the cache.
Example
Users of the transactional API should at minimum anticipate lookups that are obligated to insert
an item into the cache, and lookups which are not. If the stale-while-revalidate parameter is
set for cached items, the user should also distinguish between the insertion and revalidation
cases.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546const MAX_AGE: Duration = Duration::from_secs(3600);// perform the lookuplet lookup_tx = Transaction::lookup(CacheKey::from_static(b"my_key")) .execute()?;if let Some(found) = lookup_tx.found() { // a cached item was found; we use it now even though it might be stale, // and we'll revalidate it below use_found_item(&found);}// now we need to handle the "must insert" and "must update" casesif lookup_tx.must_insert_or_update() { if let Some(stale_found) = lookup_tx.found() { // a cached item was found and used above, and now we need to perform // revalidation let revalidation_contents = build_contents(); if should_replace(&stale_found, &revalidation_contents) { // use `insert` to replace the previous object let mut writer = lookup_tx .insert(MAX_AGE) .surrogate_keys(["my_key"]) .known_length(revalidation_contents.len() as u64) .execute()?; writer.write_all(revalidation_contents)?; writer.finish()?; } else { // otherwise update the stale object's metadata lookup_tx .update(MAX_AGE) .surrogate_keys(["my_key"]) .execute()?; } } else { // a cached item was not found, and we've been chosen to insert it let contents = build_contents(); let (mut writer, found) = lookup_tx .insert(MAX_AGE) .surrogate_keys(["my_key"]) .known_length(contents.len() as u64) // stream back the object so we can use it after inserting .execute_and_stream_back()?; writer.write_all(contents)?; writer.finish()?; // now we can use the item we just inserted use_found_item(&found); }}Methods
cancel_insert_or_update
View sourceCancels the obligation for this transaction client to insert or update a cache item.
If there are concurrent transactional lookups that were blocked waiting on this client
to provide the item, one of them will be chosen to be unblocked and given the
Transaction::must_insert_or_update() obligation.
This method should only be called when Transaction::must_insert_or_update() is true;
otherwise, a CacheError::InvalidOperation will be returned.
Parameters
- self: &Self
Returns
found
View sourceReturns a Found object for this cache item, if one is available.
Even if an object is found, the cache item might be stale and require updating. Use
Transaction::must_insert_or_update() to determine whether this transaction client is
expected to update the cached item.
Parameters
- self: &Self
Returns
insert
View sourceReturns a TransactionInsertBuilder that will perform a transactional cache insertion.
This method should only be called when Transaction::must_insert_or_update() is true;
otherwise, a CacheError::InvalidOperation will be returned when attempting to execute
the insertion.
Parameters
- self: Self
- max_age: Duration
Returns
lookup
View sourceReturns a TransactionLookupBuilder that will perform a transactional cache lookup.
See Transaction for details and an example.
Parameters
- key: CacheKey
Returns
must_insert
View sourcefn must_insert(&self) -> boolReturns true if a usable cached item was not found, and this transaction client is
expected to insert one.
Use Transaction::insert() to insert the cache item, or
Transaction::cancel_insert_or_update() to exit the transaction without providing an
item.
Parameters
- self: &Self
Returns
must_insert_or_update
View sourcefn must_insert_or_update(&self) -> boolReturns true if a fresh cache item was not found, and this transaction client is expected
to insert a new item or update a stale item.
Use:
Transaction::update()to freshen a found item by updating its metadata;Transaction::insert()to insert a new item (including object data);Transaction::cancel_insert_or_update()to exit the transaction without providing an item.
Parameters
- self: &Self
Returns
update
View sourceReturns a TransactionUpdateBuilder that will perform a transactional cache update.
Updating an item freshens it by updating its metadata, e.g. its age, without changing the object itself.
This method should only be called when Transaction::must_insert_or_update() is true
and the item is found (i.e. Transaction::found() is non-empty). Otherwise, a
CacheError::InvalidOperation will be returned when attempting to execute the update.
The method consumes the transaction. Call Transaction::found() before this method if
subsequent access to the stale cached item is needed.
Important note: the TransactionUpdateBuilder will replace all of the configuration
in the underlying cache item; if any configuration is not set on the builder, it will revert
to the default value. So, for example, if a cached item previously had some surrogate keys
set, and you want to retain them, you must call
TransactionUpdateBuilder::surrogate_keys() with the desired keys. Most configuration is
available in the Found object.
Note: the above behavior is likely to be replaced with defaulting the builder to the existing configuration, making it easier to retain the configuration by default. This change will be noted in a future changelog.
Parameters
- self: Self
- max_age: Duration
Returns