Configuring Polly library to fallback to cached values only if service is not available
Asked Answered
E

1

6

I am very new to polly. I did a bit of research but still could not find out if/how it is possible to use Polly in an elegant way to use a chached value only if a request fails. Example:

Service A wants to get data from a service B via http. I always want to get the latest data (a cache policy of a few minutes would be fine). But if the service B is down I want to be able to use the cached data as long as the service is not available.

Just using the Polly cache does not seem to solve the problem. But when using the cache only in a fallback situation, it is not filled with the latest values as it was bypassed until the failure happened. Do you get my point? THX

Enplane answered 23/3, 2020 at 14:50 Comment(0)
H
2

Whenever we are talking about resilience strategies then we mainly referring to a combination of resilient patterns. In other words in order to solve your problem you need to chain some polly polices (in the right order) to be able to tackle it. (In polly nomenclature it is called wrapping)


First let's collect the patterns:

Detecting that a Service is down

I would suggest to use the wording temporarily unavailable / unreachable because that means you want to use a resilient strategy to overcome of a transient failure. So in order to detect that a service is unavailable you can use the Circuit Breaker. It works in the following way:
This component acts as a proxy and examines the result (if any) of the requests. After a predefined number of successive / subsequent failures it will block the communication for a given time period against the downstream system. When that time period elapsed then it will allow you give it a try and see whether or not the new request is succeeding or failing.

It's worth mentioning here that Polly will throw a BrokenCircuitException whenever the proxy is blocking the outgoing requests in order to satisfy the fail fast principle.

Caching the result

Whenever you are about to cache the result of an outbound request then you should consider the following concerns:

  • Is that data is time sensitive? (So, using stale data is not an option)
  • If it time sensitive then is there any timeframe when it can be still considered as valid response?
  • Is that data is consumer specific? (So,using the same data across multiple consumer is not an option)
  • etc.

By reviewing these questions you can decide whether or not to use caching.

Using Fallback

This simple pattern provides you the ability to use something as substitute. So in your case whenever the server is unavailable then fallback to the cache.


Now let's put them together.

The ordering is important here because Polly using escalation to chain policies. When the inner policy fails then it escalates that to the outer policy.

In your case the order would be like this (from outer to inner): Fallback >> Cache >> Circuit Breaker

Of course, you can even enhance that by using Timeout and Retry as well. In that case the ordering would look like this: Fallback >> Cache >> Retry >> Circuit Breaker >> Timeout

  1. Try to execute a call under a given time-frame
  2. Scrutinize your subsequent responses and prevent cascading failure in case of transient failure
  3. Retry the call n times and wait between retries
  4. If it succeeded then cache it
  5. If it failed then use the previously cached value

For further details about PolicyWrap please read their wiki page.

Healy answered 4/6, 2020 at 7:46 Comment(2)
Thanks for the nice explanation. However I still have a problem in understanding the cache policy. I mean if there is a cached value it is returned so I do not hit the retry policy at all. And if the value expired and I finally reach the retry and it fails there is no cached value any more... you know what I mean? So it looks to me that I cannot use the cache policy but need to implement my own cache that I then use in the failover case.Enplane
@Enplane Let me amend my suggestion. The cache policy works as a read-through cache, if the value is present then it returns that otherwise it does the lookup for you. Here this the not the required behaviour. So, you couldn't use the CachePolicy, but you could use the MemoryCache. When the service is available then you should save the data there. When you call the service, but your policy throws a BrokenCircuitException, then your fallback could read the it from the cache. Fallback (cache Get) >> CircuitBreaker >> your function (network call + cache Set)Healy

© 2022 - 2024 — McMap. All rights reserved.