2

I want to use retry pattern with Aws DynamoDb. I don't know if i can use the Polly package from nuget. I researched a lot, but i learnt how to implement Polly but i couldn't find how to connect Polly with DynamoDb.

Is there any way to using Polly retry policies with Aws DynamoDb?

I'll give you an example code block and i want to know how to implement this with DynamoDb

Policy
  .WaitAndRetryAsync(
    5, 
    retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), 
    (exception, timeSpan, context) => {
      // do something
    }
  );

I am new with Aws Services, can you give me any suggestions?

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
jack
  • 65
  • 1
  • 6

1 Answers1

4

If you are using the .NET SDK for DynamoDb then you can do the following:

The to-be-decorated method

Lets suppose you have simple point query like this:

public int GetAlternativeKey(int hashKey, string rangeKey)
{
  var client = new AmazonDynamoDBClient();
  var table = Table.LoadTable(client, "LookupTable");
  var item = table.GetItem(hashKey, rangeKey);
  return (int)item["Id"];
}

The retry policy

Trigger retry in case of throttling

var retry policy = Policy
  .Handle<ThrottlingException>()
  .Or<ProvisionedThroughputExceededException>()
  .WaitAndRetry(5, 
    retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
  );

Note

Please remember to use retry policy against idempotent operations

Decorate the method with the policy

If you have defined your to-be-decorated method (and the policy as well) as synchronous

policy.Execute(() => GetAlternativeKey(hk, rk));

If you have defined them as async

await policy.ExecuteAsync(async () => await GetAlternativeKey(hk, rk));

UPDATE #1

If I understood right, these are only errors I can have which you shared.

No, that's not true. These were just examples. Most of the exceptions that can be thrown by this library is inherited from the AmazonDynamoDBException. Please see Inheritance Hierarchy section to get the full list of derived exceptions.

You talked about only use it against idempotent operations. Here what do you mean by idempotent operations? Are you suggesting me to only use retry policies with GET operations and not to use them in POST?

Idempotent operations do not cause any unwanted behaviour in case of re-execution (like duplicated inserts, multiple increment on a counter, etc.) In case of insert you can do a conditional check for not existence as a part of your putItem request. Please also check the Idempotency section of the documentation.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
  • If i understood right, these are only errors i can have which you shared. If i design my policy according to these errors and i can use my policy over `ExecuteAsync` method. I am okay in this part now, thank you very much. And you talked about only use it against idempotent operations. Here what do you mean by idempotent operations? Are you suggesting me to only use retry policies with GET operations and not to use them in POST? Actually i just need to retry a couple times if i cannot get/set the data from DynamoDb due to momentary network issues. I believe this way will be more resilient. – jack Aug 14 '22 at 11:07
  • 2
    @jack I've updated my post to provide answer for your questions. Please revisit it – Peter Csala Aug 14 '22 at 19:57
  • why the exponential increase in wait, rather than a fixed (say) 15 seconds? – Kappacake Oct 25 '22 at 10:41
  • `GetAlternativeKey(hk, rk)` returns an int. How do you capture that via the `policy.Execute` ? – Kappacake Oct 25 '22 at 10:47
  • @Kappacake *why the exponential increase in wait, rather than a fixed (say) 15 seconds?* I've used the same `sleepDurationProvider` as the OP. If you are asking why should we use exponential backoff then I would suggest to read [this project's readme](https://github.com/Polly-Contrib/Polly.Contrib.WaitAndRetry). – Peter Csala Oct 25 '22 at 11:05
  • @Kappacake *GetAlternativeKey(hk, rk) returns an int. How do you capture that via the policy.Execute?* You need to adjust the definition of the policy from `Policy.Handle<...` to `Policy.Handle<...`. After this adjustment the `Execute` will return an int or throws an exception. – Peter Csala Oct 25 '22 at 11:08
  • 1
    Thanks for the answer! I actually went for `ExecuteAndCapture` which returns whatever value the inner function returns. Regarding the exponential increase in wait, still not sure if that is the best strategy in my scenario, which is similar to the OP but I'm getting the Rate Exceeded error from AWS CloudFormation, EC2 and other SDKs bits. However, AWS itself recommends an exponential increase in wait, so I'll stick with this unless I find any problems. ([Link to the relevant AWS doc](https://aws.amazon.com/premiumsupport/knowledge-center/cloudformation-rate-exceeded-error/)) – Kappacake Oct 25 '22 at 13:44