Skip to content

chore: Implement LazyValue helper#45

Merged
dazuma merged 1 commit into
googleapis:mainfrom
dazuma:pr/lazyvalue
Oct 26, 2023
Merged

chore: Implement LazyValue helper#45
dazuma merged 1 commit into
googleapis:mainfrom
dazuma:pr/lazyvalue

Conversation

@dazuma

@dazuma dazuma commented Oct 25, 2023

Copy link
Copy Markdown
Contributor

This helper is the core piece of the updated implementation. It provides:

  • Lazy computation/evaluation of data. The object is constructed with a block that specifies how to compute the value (e.g. make a request to the metadata server), but it isn't actually executed until the first time the value is accessed.
  • Caching/memoization so a value gets computed only once, and the cached result is returned on subsequent accesses.
  • Expiration of that memoization, for information such as access tokens.
  • Retry, tailored especially for metadata server scenarios (e.g. a small number of retries to handle network instability, and a warmup period of retries to handle the initialization case).
  • Robust thread safety, assuring in particular that, modulo retries and expiration, at most one thread will ever do the computation/lookup for any particular value.
  • Both individual value and key-value interfaces.

Some of this functionality is similar to that provided by Concurrent::Delay and Concurrent::LazyRegister, but nothing in concurrent-ruby provides everything we need.

@dazuma dazuma requested a review from a team October 25, 2023 18:06
# configurable, as is the retry "interval", i.e. the time since the last
# failure before an access will retry the computation.
#
# A computation can cause its result (or error) to expire after a

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the default expiration that we're setting for cache expiry?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By default, memoized values never expire. I'll make that more explicit in the documentation.

# @raise [Exception] if a fatal error happened, or retries have been
# exhausted.
#
def await *extra_args, transient_errors: nil, max_tries: 1, max_time: nil, delay_epsilon: 0.0001

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious why we're not using retry gem for retrying.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it's not a simple retry, but one whose conditions and delays are dynamic and tied closely to information from the state of the LazyValue. For example, to determine the delay until the next retry, we need to get the wait time expiration, that is, the next time the computation engine will allow another computation attempt to start.

@dazuma dazuma merged commit f009330 into googleapis:main Oct 26, 2023
@dazuma dazuma deleted the pr/lazyvalue branch October 26, 2023 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants