efcore icon indicating copy to clipboard operation
efcore copied to clipboard

Look into EF's story with the Polly resilience framework

Open roji opened this issue 2 years ago • 4 comments

Polly is a resilience framework that handle stuff like retrying on transient failure, circuit breakers and similar related features. EF has its own retrying strategy for transient failures, but Polly is likely to have various features beyond what we provide out-of-the-box.

We should look into the EF can work with Polly, make sure we have a good story there. This may involve e.g. an integration package that makes it easier to plug Polly in as an execution strategy in EF, etc.

roji avatar Mar 22 '23 21:03 roji

This could be really interesting! Looking into Polly right now for a Rest API client. Having the possibility to reuse a single resilience framework in an application, regardless of the connection type, would be really interesting to keep implementation simple (only a single framework/policy format, ie Polly, to learn and leverage)!

ggirard07 avatar May 14 '23 18:05 ggirard07

@ggirard07 note that the resilience policy characteristics used for database operations are probably not the same as what you'd use for e.g. an HTTP client call: at the very least, detecting temporary failures is a completely different thing. But I agree that there's value in being able to use the same infrastructure here.

roji avatar May 17 '23 09:05 roji

I think the integration package here should be one initially divorced from EF core - for user initiated transactions.

var retry = GetPollyRetryPolicy();
await retry.ExecuteAsync(()=> {
    var connection = GetAdoNetConnection(); // grab new conn each attempt in case its broken?
    // stereotypical transaction code here.
    connection.BeginTransaction(); // etc 
   
 })

Points to mention:-

  • Each database provider will have specific errors it deems as valid for a transaction retry - so the GetPollyRetry() needs to return a policy that's configured for the correct Ado.net provider that you are using. This is where I think provider specific polly packages can come in.
  • Notice I create a new connection in the retry. I am wondering whether you'd need two different policies (I hope not) one for handling connection level vs transaction level I.e
    var retry = GetPollyConnectionRetryPolicy();
await retry.ExecuteAsync(()=> {
       var connection = GetAdoNetConnection(); // grab new conn each attempt in case its broken?
       var transRetry = GetPollyTransactionRetryPolicy();
      await transRetry.ExecuteAsync(()=> {
        // stereotypical transaction code here.
        connection.BeginTransaction(); // etc
      });
  });

Once the polly policies are available at this level, then EF can just participate in the transaction as it ordinarily does.

dazinator avatar Oct 08 '24 19:10 dazinator

Re provider-specific Polly packages for detecting transient exceptions, that's what the DbException.IsTransient property was originally meant to solve. However, that's not implemented by all providers and what should be considered transient (i.e. retried) isn't always the clear/universal.

roji avatar Oct 08 '24 20:10 roji