Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Артём Микулич «Как интегрироваться с (не-)надёжным third-party API при помощи Polly»

Артём Микулич «Как интегрироваться с (не-)надёжным third-party API при помощи Polly»

Интеграция с third-party сервисами дело неблагодарное. Когда мы делаем запросы в сторонний сервис, всегда есть вероятность, что что-то может пойти «не так» — отвалится сеть, сервис выбросит 429 Too Many Requests и т.д.

Зачастую мы не можем устранить причину таких проблем, но в наших силах минимизировать возникающий ущерб. Вы наверняка слышали о Retry-логике, кешировании, fallback-механизмах. До появления библиотеки Polly всё это мы изобретали сами. Но теперь у нас есть отличный инструмент, который сохранит наше время и нервы.

Ceecdee9ee77b63d81100be62b7e1090?s=128

DotNetRu

July 23, 2020
Tweet

Transcript

  1. How to integrate with a crappy Api Artem Mikulich, Tech

    Lead at ISsoft Solutions 1
  2. 2

  3. 3 • 429 - too many requests Possible root cause

    • Network lag • Dead lock • Server reboot • Other
  4. 4 Solution? Do NOT make http requests

  5. 5 Solution? Cross fingers

  6. 6 Solution? Re-invent the wheel

  7. 7 Solution? Find at nuget

  8. 8

  9. Agenda • Case #1: sporadic errors • Case #2: timeout

    • Case #3: dynamic policies • Case #4: caching • Advanced cases 9
  10. 10 Case #1: Sporadic errors

  11. Demo 11

  12. Retry 12 public void ConfigureServices(IServiceCollection services) { //... IAsyncPolicy<HttpResponseMessage> retry

    = Policy .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode) .RetryAsync(3); services.AddHttpClient<CrapyWeatherApiClient>((client) => {/* ... */}) .AddPolicyHandler(retry); }
  13. Demo: Retry 13

  14. 14 Case #2: Timeout

  15. 15 Possible root cause • Network lag • Database lock

    • Server warms up • Other • Database stats reset
  16. 16

  17. Handle Timeout 17 var retry = Policy .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)

    .Or<TimeoutRejectedException>() .RetryAsync(3); var timeoutPolicy = Policy .TimeoutAsync(TimeSpan.FromSeconds(30), (ctx, t, task, e) => {/* ... */}); services.AddHttpClient<CrapyWeatherApiClient>((client) => {/* ... */}) .AddPolicyHandler(retry.WrapAsync(timeoutPolicy));
  18. Demo: Handle Timeout 18

  19. 19 Case #3: dynamic policies • Specific url (e.g. /reports)

    • Http method (GET/POST/PUT) • Metrics (# of requests, date/time) • Other
  20. 20 Policy Registry var registry = services.AddPolicyRegistry(); registry.Add("RetryPolicy", policy); services.AddHttpClient<CrapyWeatherApiClient>((client)

    => {/* ... */}) .AddPolicyHandlerFromRegistry((policyRegistry, request) => { if (request.Method == HttpMethod.Get) { return registry.Get<IAsyncPolicy<HttpResponseMessage>>("RetryPolicy"); } return Policy.NoOpAsync<HttpResponseMessage>(); });
  21. Demo: dynamic policies 21

  22. 22 Case #4: Caching

  23. Policy Registry extensions policyRegistry.GetCachePolicyFor<SampleApiClient>(); policyRegistry.AddCachePolicyFor<SampleApiClient>( cacheProvider, TimeSpan.FromSeconds(60)); 23

  24. Demo: Caching 24

  25. Advanced policies: Bulkhead isolation rate limit 25

  26. Advanced policies: Circuit Breaker 26

  27. Thanks for listening! 27

  28. Links https://github.com/amikulich/polly-best-practices https://github.com/amikulich/easyextensions.polly https://www.nuget.org/packages/EasyExtensions.Polly/ https://www.facebook.com/devinjacket https://www.youtube.com/channel/UCUwH3coyAnGL7zYCELMhjKA 28