﻿
{"id":20283,"date":"2021-01-22T00:08:49","date_gmt":"2021-01-22T00:08:49","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=20283"},"modified":"2021-01-22T00:09:54","modified_gmt":"2021-01-22T00:09:54","slug":"net-core-5-0-retry-pattern-timeout-ve-circuit-breaker-polly","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/net-core-5-0-retry-pattern-timeout-ve-circuit-breaker-polly\/","title":{"rendered":".NET Core 5.0 &#8211; Retry Pattern, Timeout ve Circuit Breaker | Polly"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Client ve server aras\u0131ndaki haberle\u015fmede request\/response esas\u0131na dayanan bir proje d\u00fc\u015fleyelim&#8230; Client&#8217;\u0131n, ihtiyac\u0131 do\u011frultusunda server&#8217;a request tabanl\u0131 isteklerde bulunabildi\u011fini ve elde edilen response neticesinde gelen verileri i\u015fleyebildi\u011fini&#8230; Evet, biliyorum. Bu durum g\u00fcn\u00fcm\u00fcz\u00fcn en temel esas\u0131. Haliyle <em>d\u00fc\u015flenecek ne var burada hoca!<\/em> dedi\u011finizi de duyar gibiyim&#8230; Tabi ki de, sizleri bilinen bir k\u00fclt\u00fcr \u00fczerinden beyhude d\u00fc\u015flere s\u00fcr\u00fcklemek gibi bir niyetim yok. Hatta biliyorum ki, bir \u00e7o\u011funuz bu yakla\u015f\u0131m\u0131 gerekti\u011fi taktirde g\u00f6z\u00fcn\u00fcz kapal\u0131 kullanabilmekte ve client ile server ileti\u015fimini sa\u011flayabilmektedir. Ama \u015funu da biliyorum ki, bu yakla\u015f\u0131m\u0131 kullanan az\u0131msanmayacak bir kitlenin client ile server aras\u0131ndaki haberle\u015fme esnas\u0131nda server&#8217;da ya\u015fanabilecek olas\u0131 hatalara kar\u015f\u0131 \u00f6nlem almad\u0131\u011f\u0131n\u0131 da&#8230; <\/p>\n<p>Evet, bu i\u00e7eri\u011fimizde client ile server aras\u0131ndaki request\/response temelli haberle\u015fme s\u00fcre\u00e7lerinde nelere dikkat edilmesi gerekti\u011fini ele alacak ve yap\u0131lan request neticesinde server&#8217;da meydana gelebilecek olas\u0131 bir hatadan yahut kesintiden kaynakl\u0131 ya\u015fanan ba\u015far\u0131s\u0131zl\u0131k durumlar\u0131nda client&#8217;\u0131n ne gibi davran\u0131\u015flar g\u00f6stermesi gerekti\u011fi \u00fczerine fark\u0131ndal\u0131k yarat\u0131yor olaca\u011f\u0131z.<\/p>\n<p>\u015eimdi, ilk olarak yukar\u0131da sizlere yans\u0131tmaya \u00e7al\u0131\u015ft\u0131\u011f\u0131m fark\u0131ndal\u0131\u011f\u0131 net masaya yat\u0131rarak ba\u015flayal\u0131m. Bunun i\u00e7in a\u015fa\u011f\u0131daki materyal konuya dair gayet yeterli malzeme verecektir;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n            HttpClient httpClient = new HttpClient();\r\n            var message = await httpClient.GetAsync(&quot;https:\/\/localhost:5001\/api\/products&quot;);\r\n            var content = message.Content.ReadAsStringAsync();\r\n            Console.WriteLine(content.Result);\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere, bu kod herhangi bir uygulaman\u0131n herhangi bir noktas\u0131nda \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131 vakit, belirtilen endpoint&#8217;e bir GET iste\u011finde bulunacak ve sonucu elde edecektir. Bu gayet a\u015fikar! Lakin bu kodu kullanan client&#8217;\u0131n yapt\u0131\u011f\u0131 request neticesinde server&#8217;da bir hata meydana gelirse ne olacak? Hi\u00e7 bunu d\u00fc\u015f\u00fcnd\u00fcn\u00fcz m\u00fc?<\/p>\n<p>Hatta ilgili API&#8217;\u0131n detay\u0131n\u0131 da a\u015fa\u011f\u0131ya alal\u0131m ve gelen istekte ya\u015fanacak s\u0131k\u0131nt\u0131y\u0131 garantiye alal\u0131m&#8230;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;ApiController]\r\n    &#x5B;Route(&quot;api\/&#x5B;controller]&quot;)]\r\n    public class ProductsController : ControllerBase\r\n    {\r\n        &#x5B;HttpGet]\r\n        public string Get()\r\n        {\r\n            throw new Exception(&quot;Hata!&quot;);\r\n        }\r\n    }\r\n<\/pre>\n<p>Dikkat ederseniz API i\u00e7eride bir Exception f\u0131rlatmaktad\u0131r. Bu durum, connection kopmas\u0131 yahut sistem \u00e7\u00f6kmesi gibi run time&#8217;da al\u0131nan farkl\u0131 bir hatadan da kaynaklan\u0131yor olabilirdi. En nihayetinde request g\u00f6nderilen server&#8217;\u0131n s\u00fcre\u00e7te ya\u015fad\u0131\u011f\u0131 bir aksakl\u0131\u011fa kar\u015f\u0131 client&#8217;\u0131n alaca\u011f\u0131 tutuma odaklan\u0131rsak e\u011fer client&#8217;\u0131n genel ge\u00e7er davran\u0131\u015f\u0131 a\u015fa\u011f\u0131daki gibi olacakt\u0131r.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly.png\" alt=\".NET Core 5.0 - Retry Pattern | Polly\" width=\"874\" height=\"544\" class=\"aligncenter size-full wp-image-20626\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly.png 874w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly-300x187.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly-768x478.png 768w\" sizes=\"auto, (max-width: 874px) 100vw, 874px\" \/><\/a>\u0130\u015fte&#8230; Client&#8217;\u0131n yapt\u0131\u011f\u0131 request neticesinde e\u011fer server&#8217;da bir hata meydana gelirse client bundan haberdar edilmekte lakin kodun ak\u0131\u015f\u0131 devam edece\u011finden dolay\u0131 bu iste\u011fin bir daha esamesi okunmamaktad\u0131r. Lakin bu istek bizim i\u00e7in \u00f6nemliyse ve server&#8217;da ki ya\u015fanan istisnai durum gelip ge\u00e7ici bir hataysa! B\u00f6yle bir ahvalde iste\u011fi es ge\u00e7mektense, bir m\u00fcddet sonra tekrar denemek daha ak\u0131ll\u0131ca ve amaca d\u00f6n\u00fck olmayacak m\u0131? Hatta server&#8217;da ya\u015fanan sorunun ne kadar s\u00fcre sonra neticelenece\u011fi kesin bilinemeyece\u011finden dolay\u0131 belirli bir s\u00fcre sonra tekrar edecek olan request&#8217;i, izafi olarak ayarlanm\u0131\u015f bir ka\u00e7 periyot e\u015fli\u011finde tekrarl\u0131 yapmak ve t\u00fcm bu isteklere ra\u011fmen hala hata \u00e7\u00f6z\u00fclemediyse o zaman iste\u011fi es ge\u00e7mek en do\u011frusu olmayacak m\u0131?<\/p>\n<p>Evet&#8230; San\u0131r\u0131m ayn\u0131 fikirdeyiz \ud83d\ude42 Tabi ki de do\u011frusu bu olacakt\u0131r.<\/p>\n<p><em>Peki b\u00f6yle bir durumda ne yapmal\u0131y\u0131z? Yani client&#8217;\u0131n yapt\u0131\u011f\u0131 request neticesinde server&#8217;da bir hata varsa bu duruma kar\u015f\u0131 davran\u0131\u015f\u0131m\u0131z\u0131 belirleyebilmek i\u00e7in nas\u0131l aksiyon almal\u0131y\u0131z?<\/em><\/p>\n<p>Yap\u0131lan bir i\u015flemin herhangi bir sebepten dolay\u0131 ask\u0131ya u\u011framas\u0131 durumunda, o i\u015flemi tekrar edebilmek i\u00e7in Retry Pattern&#8217;i kullanabiliriz. Haliyle client&#8217;\u0131n g\u00f6nderdi\u011fi request&#8217;in server&#8217;da ki herhangi bir sebepten dolay\u0131 kaynaklanan hatayla kar\u015f\u0131la\u015fmas\u0131 neticesinde Retry Pattern uygulanarak belirli periyotlarda bu istek tekrar edilebilir ve meydana gelen hatan\u0131n getirdi\u011fi zaafiyet m\u00fcmk\u00fcn mertebe ortadan kald\u0131r\u0131lmaya \u00e7al\u0131\u015f\u0131labilir.<\/p>\n<h3 style=\"color:purple;\">Retry Pattern Nedir?<\/h3>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly-1-156x300.png\" alt=\".NET Core 5.0 - Retry Pattern | Polly\" width=\"156\" height=\"300\" class=\"alignleft size-medium wp-image-20635\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly-1-156x300.png 156w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly-1.png 502w\" sizes=\"auto, (max-width: 156px) 100vw, 156px\" \/><\/a>Retry pattern, yandaki g\u00f6r\u00fcnt\u00fcde g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere client&#8217;\u0131n yapm\u0131\u015f oldu\u011fu iste\u011fin ba\u015far\u0131l\u0131 olmas\u0131na odakl\u0131 tekrar edilmesini sa\u011flayan bir tasar\u0131m desenidir. Yap\u0131lan request neticesinde hata al\u0131nd\u0131ysa e\u011fer bu hatan\u0131n k\u0131sa s\u00fcreli\u011fine olma ihtimaline istinaden kullan\u0131c\u0131ya fark ettirmeksizin request&#8217;i arkaplanda tekrar yenileme \u00fczerine kurulu bir mant\u0131\u011fa sahiptir.<\/p>\n<p>Yukar\u0131daki sat\u0131rlarda da ifade edilmeye \u00e7al\u0131\u015f\u0131ld\u0131\u011f\u0131 gibi server&#8217;da t\u00fcrl\u00fc sebeplerden dolay\u0131 meydana gelen aksamalar neticesinde ilgili iste\u011fi <u>taraf\u0131m\u0131zca bildirilen<\/u> periyotlar kadar tekrar edebilmekte ve b\u00f6ylece iste\u011fin mahiyetindeki \u00f6nem arz eden operasyona g\u00f6sterilen hassasiyeti artt\u0131rmay\u0131 sa\u011flamaktad\u0131r.<\/p>\n<p>Retry Pattern, bir tasar\u0131m deseni oldu\u011fu i\u00e7in OOP nimetlerinden faydalanarak in\u015fa edilmesi gereken stratejik bir matemati\u011fe sahiptir. \u0130stendi\u011fi taktirde bu matemati\u011fe uygun \u00e7al\u0131\u015fma ger\u00e7ekle\u015ftirilerek uygulanabilir. Lakin bu ve bunun gibi senaryolara uygun tasarlanm\u0131\u015f ve i\u00e7erisinde hali haz\u0131rda efektif i\u015flevsel fonksiyonellikler bar\u0131nd\u0131ran <em><strong>Polly K\u00fct\u00fcphanesi<\/strong><\/em>ni kullanmay\u0131 tercih edebilirsiniz.<\/p>\n<h3 style=\"color:purple;\">Polly K\u00fct\u00fcphanesi Nedir?<\/h3>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly-2.png\" alt=\".NET Core 5.0 - Retry Pattern | Polly\" width=\"128\" height=\"128\" class=\"alignright size-full wp-image-20643\" \/><\/a>Servisler aras\u0131 haberle\u015fme s\u00fcre\u00e7lerinde bir \u00e7ok pattern&#8217;\u0131 uygulamam\u0131z\u0131 sa\u011flayan operasyonellikler bar\u0131nd\u0131ran, Retry, Circuit Breaker, Timeout, Bulkhead Isolation ve Fallback gibi senaryolarda kullan\u0131labilir niteli\u011fe sahip open source bir k\u00fct\u00fcphanedir.<\/p>\n<p>Bizler bu i\u00e7eri\u011fimizde, Retry Pattern&#8217;\u0131 Polly k\u00fct\u00fcphanesi ile uygulamay\u0131 ele al\u0131yor olaca\u011f\u0131z.<\/p>\n<h4 style=\"color:orange;\">Polly K\u00fct\u00fcphanesi \u0130le Retry Pattern Operasyonlar\u0131<\/h4>\n<p><a href=\"https:\/\/www.nuget.org\/packages\/Polly\/\" rel=\"noopener noreferrer\" target=\"_blank\">Polly<\/a> k\u00fct\u00fcphanesini kullanabilmek i\u00e7in her \u015feyden \u00f6nce ilgili k\u00fct\u00fcphanenin a\u015fa\u011f\u0131daki komut e\u015fli\u011finde projeye y\u00fcklenmesi gerekmektedir.<\/p>\n<div style=\"text-align:center;\"><code style=\"color:red;font-size:12px;\">Install-Package Polly<\/code><\/div>\n<p>Y\u00fckleme i\u015flemi yap\u0131ld\u0131ktan sonra art\u0131k Polly k\u00fct\u00fcphanesinin server&#8217;da al\u0131nan olas\u0131 hatalara kar\u015f\u0131, hata kontrol politikalar\u0131n\u0131 olu\u015fturmam\u0131z gerekecektir. Bunlar <strong>Fault-Handling Reactive Policies(Hata \u0130\u015fleme Politikalar\u0131)<\/strong> olarak nitelendirilmektedir.<\/p>\n<ul>\n<li><strong><em>Yakalanmas\u0131 \u0130stenilen Hatalar\u0131n Tan\u0131mlanmas\u0131<\/em><\/strong>\n<ul>\n<li><em>Tek bir hata tipine g\u00f6re \u00e7al\u0131\u015f\u0131laca\u011f\u0131n\u0131 belirtebilmekteyiz.<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n  .Handle&lt;HttpRequestException&gt;()\r\n<\/pre>\n<\/li>\n<li><em>Ko\u015fullu hata tipine g\u00f6re \u00e7al\u0131\u015f\u0131laca\u011f\u0131n\u0131 belirtebilmekteyiz.<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n  .Handle&lt;SqlException&gt;(ex =&gt; ex.Number == 1205)\r\n<\/pre>\n<\/li>\n<li><em>Birden fazla hata tipine g\u00f6re \u00e7al\u0131\u015f\u0131laca\u011f\u0131n\u0131 belirtebilmekteyiz.<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n  .Handle&lt;HttpRequestException&gt;()\r\n  .Or&lt;OperationCanceledException&gt;()\r\n<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<li><strong><em>\u0130\u015flenmesi \u0130stenilen Return Type&#8217;lar\u0131n\u0131n Tan\u0131mlanmas\u0131<\/em><\/strong>\n<ul>\n<li><em>D\u00f6n\u00fc\u015f De\u011ferini Ko\u015fulla \u0130\u015fleme<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n  .HandleResult&lt;HttpResponseMessage&gt;(r =&gt; r.StatusCode == HttpStatusCode.NotFound)\r\n<\/pre>\n<\/li>\n<li><em>Birden \u00c7ok D\u00f6n\u00fc\u015f De\u011feri \u0130\u015fleme<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n  .HandleResult&lt;HttpResponseMessage&gt;(r =&gt; r.StatusCode == HttpStatusCode.InternalServerError)\r\n  .OrResult(r =&gt; r.StatusCode == HttpStatusCode.BadGateway)\r\n<\/pre>\n<\/li>\n<li><em>D\u00f6n\u00fc\u015f De\u011ferlerini Equals \u015eeklinde Direkt \u015eart Olarak Verilebildi\u011fi Durum<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n  .HandleResult&lt;HttpStatusCode&gt;(HttpStatusCode.InternalServerError)\r\n  .OrResult(HttpStatusCode.BadGateway)\r\n<\/pre>\n<\/li>\n<li><em>Hem Hatalar\u0131n Hem de D\u00f6n\u00fc\u015f De\u011ferlerinin Tek Bir Politikada Ele Al\u0131nmas\u0131<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nHttpStatusCode&#x5B;] httpStatusCodesWorthRetrying = {\r\n   HttpStatusCode.RequestTimeout, \/\/ 408\r\n   HttpStatusCode.InternalServerError, \/\/ 500\r\n   HttpStatusCode.BadGateway, \/\/ 502\r\n   HttpStatusCode.ServiceUnavailable, \/\/ 503\r\n   HttpStatusCode.GatewayTimeout \/\/ 504\r\n}; \r\nHttpResponseMessage result = await Policy\r\n  .Handle&lt;HttpRequestException&gt;()\r\n  .OrResult&lt;HttpResponseMessage&gt;(r =&gt; httpStatusCodesWorthRetrying.Contains(r.StatusCode))\r\n  .RetryAsync(...)\r\n  .ExecuteAsync( \/* some Func&lt;Task&lt;HttpResponseMessage&gt;&gt; *\/ )\r\n<\/pre>\n<\/li>\n<\/li>\n<\/ul>\n<\/li>\n<li><strong><em>Hatalar\u0131n Ne \u015eekilde \u0130\u015flenece\u011finin Tan\u0131mlanmas\u0131<\/em><\/strong>\n<ul>\n<li><em>Tek Bir Kez Yeniden \u0130stek G\u00f6nderme<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n  .Handle&lt;SomeExceptionType&gt;()\r\n  .Retry()\r\n<\/pre>\n<\/li>\n<li><em>Bir \u00c7ok Kez Yeniden \u0130stek G\u00f6nderme<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n  .Handle&lt;SomeExceptionType&gt;()\r\n  .Retry(3)\r\n<\/pre>\n<\/li>\n<li><em>Bir \u00c7ok Kez Yeniden \u0130stek G\u00f6nderme Durumunda Fonksiyon Tetikleme<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n    .Handle&lt;SomeExceptionType&gt;()\r\n    .Retry(3, onRetry: (exception, retryCount) =&gt;\r\n    {\r\n        \/\/Her yeniden denemeden \u00f6nce gerekli loglama vs. operasyonlar\u0131 burada ger\u00e7ekle\u015ftirilir.\r\n    });\r\n<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<li><strong><em>Ba\u015far\u0131l\u0131 Olana Kadar Yeniden \u0130stek G\u00f6nderme<\/em><\/strong>\n<ul>\n<li><em>Sonsuza Kadar \u0130stek G\u00f6nderme<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n  .Handle&lt;SomeExceptionType&gt;()\r\n  .RetryForever()\r\n<\/pre>\n<\/li>\n<li><em>Sonsuza Kadar \u0130stek G\u00f6nderirken, Al\u0131nan Hatay\u0131 Yakalama<\/em>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n  .Handle&lt;SomeExceptionType&gt;()\r\n  .RetryForever(onRetry: exception =&gt;\r\n  {\r\n        \/\/Her yeniden denemeden \u00f6nce gerekli loglama vs. operasyonlar\u0131 burada ger\u00e7ekle\u015ftirilir.     \r\n  });\r\n<\/pre>\n<\/li>\n<\/ul>\n<\/li>\n<\/li>\n<\/ul>\n<h4 style=\"color:orange;\">\u00d6rnek \u00c7al\u0131\u015fma<\/h4>\n<p>Polly k\u00fct\u00fcphanesi ile \u00f6rnek bir Retry operasyonu i\u00e7in a\u015fa\u011f\u0131daki kod blo\u011funu inceleyebilirsiniz;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n            await Policy.Handle&lt;Exception&gt;().RetryAsync(5,\r\n                  (e, r) =&gt;\r\n                  {\r\n                      Console.WriteLine(&quot;Tekrar deneniyor...&quot;);\r\n                  }).ExecuteAsync(async () =&gt;\r\n                  {\r\n                      HttpClient httpClient = new HttpClient();\r\n                      var message = await httpClient.GetAsync(&quot;https:\/\/localhost:5001\/api\/products&quot;);\r\n                      var content = message.Content.ReadAsStringAsync();\r\n                      Console.WriteLine(content.Result);\r\n                  });\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Polly.gif\" alt=\".NET Core 5.0 - Retry Pattern | Polly\" width=\"800\" height=\"393\" class=\"aligncenter size-full wp-image-20672\" \/><\/a><\/p>\n<h4 style=\"color:orange;\">Timeout Operasyonlar\u0131<\/h4>\n<p>Polly&#8217;de Timeout; Optimistic ve Pessimistic olmak \u00fczere ikiye ayr\u0131lmaktad\u0131r.<\/p>\n<ul>\n<li><strong>Optimistic Timeout<\/strong><br \/>\nOptimistic Timeout, CancellationToken arac\u0131l\u0131\u011f\u0131yla \u00e7al\u0131\u015fmaktad\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n            var policy1 = Policy.Handle&lt;Exception&gt;().RetryAsync(5, (e, i) =&gt; Console.WriteLine(&quot;Tekrar deneniyor...&quot;));\r\n            var policy2 = Policy.TimeoutAsync(125);\r\n            var combinePolicy = policy1.WrapAsync(policy2);\r\n            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();\r\n\r\n            await combinePolicy.ExecuteAsync(async (cancellationToken) =&gt;\r\n            {\r\n                HttpClient httpClient = new HttpClient();\r\n                var message = await httpClient.GetAsync(&quot;https:\/\/localhost:5001\/api\/products&quot;);\r\n                var content = message.Content.ReadAsStringAsync();\r\n                Console.WriteLine(content.Result);\r\n            }, cancellationTokenSource.Token);\r\n<\/pre>\n<p>Optimistic Timeout, kesinlikle bir CancellationToken bekleyecektir.\n<\/li>\n<li><strong>Pessimistic Timeout<\/strong><br \/>\nPessimistic Timeout, CancellationToken olmasa dahi bildirilen zaman\u0131n dolmas\u0131 neticesinde net hata f\u0131rlatmaktad\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n            var policy1 = Policy.Handle&lt;Exception&gt;().RetryAsync(5, (e, i) =&gt; Console.WriteLine(&quot;Tekrar deneniyor...&quot;));\r\n            var policy2 = Policy.TimeoutAsync(125, Polly.Timeout.TimeoutStrategy.Pessimistic);\r\n            var combinePolicy = policy1.WrapAsync(policy2);\r\n            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();\r\n\r\n            await combinePolicy.ExecuteAsync(async (cancellationToken) =&gt;\r\n            {\r\n                HttpClient httpClient = new HttpClient();\r\n                var message = await httpClient.GetAsync(&quot;https:\/\/localhost:5001\/api\/products&quot;);\r\n                var content = message.Content.ReadAsStringAsync();\r\n                Console.WriteLine(content.Result);\r\n            });\r\n<\/pre>\n<\/li>\n<\/ul>\n<h4 style=\"color:orange;\">Circuit Breaker<\/h4>\n<p>Circuit Breaker, servisler aras\u0131ndaki \u00e7a\u011fr\u0131lar\u0131 d\u00fczenleyen bir pattern&#8217;d\u0131r. A\u015fa\u011f\u0131daki diyagramda oldu\u011fu gibi &#8216;Service A&#8217;, &#8216;Service B&#8217;ye bir istek g\u00f6nderdi\u011finde &#8216;Service B&#8217;de istek gecikir yahut bir hata meydana gelirse &#8216;Service A&#8217; taraf\u0131nda da bu istek yukar\u0131da ele ald\u0131\u011f\u0131m\u0131z gibi Retry Pattern ile tekrar ger\u00e7ekle\u015ftirilir. Ancak yeniden denenen isteklerin say\u0131s\u0131 a\u015f\u0131r\u0131ya ka\u00e7arsa e\u011fer kullan\u0131c\u0131 deneyimi a\u00e7\u0131s\u0131ndan olumlu olan bu eylem grafi\u011fi olumsuza seyredebilir ve fazladan y\u00fck ve gecikme neticesinden maliyetli olabilir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly-1.png\" alt=\".NET Core 5.0 - Retry Pattern, Timeout ve Circuit Breaker | Polly\" width=\"685\" height=\"262\" class=\"aligncenter size-full wp-image-20679\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly-1.png 685w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly-1-300x115.png 300w\" sizes=\"auto, (max-width: 685px) 100vw, 685px\" \/><\/a><\/p>\n<p>\u0130\u015fte b\u00f6yle bir durumda, yap\u0131lan istek neticesinde cevap beklenenden uzun s\u00fcrd\u00fc\u011f\u00fcnde yahut hata meydana geldi\u011finde yap\u0131lan yeniden isteklerin yan\u0131nda Circuit Breaker ile belirlenen deneme s\u0131n\u0131r\u0131 a\u015f\u0131ld\u0131\u011f\u0131 taktirde bu istekler son bulacakt\u0131r. B\u00f6ylece s\u00fcre\u00e7teki olumsuz durum son kullan\u0131c\u0131ya uygun bir dille izah edilerek, l\u00fczumsuz beklemenin \u00f6n\u00fcne ge\u00e7ilmi\u015f olunacakt\u0131r.<\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly.png\" alt=\".NET Core 5.0 - Retry Pattern, Timeout ve Circuit Breaker | Polly\" width=\"727\" height=\"260\" class=\"aligncenter size-full wp-image-20682\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly.png 727w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly-300x107.png 300w\" sizes=\"auto, (max-width: 727px) 100vw, 727px\" \/><\/a><\/p>\n<p>Belirlenen say\u0131da istekten sonra Circuit Breaker ile devreyi kesebilmek i\u00e7in a\u015fa\u011f\u0131daki politikan\u0131n kullan\u0131lmas\u0131 yeterlidir;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPolicy\r\n            await Policy.Handle&lt;Exception&gt;().CircuitBreakerAsync(2, TimeSpan.FromMinutes(10), (e, t) =&gt;\r\n            {\r\n                Console.WriteLine(&quot;Tekrar deneniyor...&quot;);\r\n            }, () =&gt;\r\n            {\r\n                Console.WriteLine(&quot;Reset&quot;);\r\n            }).ExecuteAsync(async () =&gt;\r\n            {\r\n                HttpClient httpClient = new HttpClient();\r\n                var message = await httpClient.GetAsync(&quot;https:\/\/localhost:5001\/api\/products&quot;);\r\n                var content = message.Content.ReadAsStringAsync();\r\n                Console.WriteLine(content.Result);\r\n            });\r\n<\/pre>\n<h4 style=\"color:orange;\">Asp.NET Core Retry Pattern &#038; Timeout<\/h4>\n<p>Asp.NET Core uygulamalar\u0131nda Polly k\u00fct\u00fcphanesini kullanabilmek i\u00e7in <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.Extensions.Http.Polly\/\" rel=\"noopener noreferrer\" target=\"_blank\">Microsoft.Extensions.Http.Polly<\/a> paketinin uygulamaya y\u00fcklenmesi gerekmektedir.<\/p>\n<p>Ard\u0131ndan &#8216;Startup.cs&#8217; dosyas\u0131ndaki a\u015fa\u011f\u0131daki servis konfig\u00fcrasyonlar\u0131n\u0131n yap\u0131lmas\u0131 gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n.\r\n.\r\n.\r\n        public void ConfigureServices(IServiceCollection services)\r\n        {\r\n            .\r\n            .\r\n            .\r\n            services.AddControllers();\r\n            services.AddHttpClient(&quot;myClient&quot;)\r\n                .AddPolicyHandler(Policy.TimeoutAsync(20, async (context, timeSpan, task) =&gt;\r\n                {\r\n                    Console.WriteLine(&quot;Zaman a\u015f\u0131m\u0131!&quot;);\r\n                }).AsAsyncPolicy&lt;HttpResponseMessage&gt;())\r\n                .AddTransientHttpErrorPolicy(policy =&gt; policy.RetryAsync(3, (d, r) =&gt;\r\n                 {\r\n                     Console.WriteLine(&quot;Tekrar deneniyor.&quot;);\r\n                 }));\r\n            .\r\n            .\r\n            .\r\n        }\r\n.\r\n.\r\n.\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly-2.png\" alt=\".NET Core 5.0 - Retry Pattern, Timeout ve Circuit Breaker | Polly\" width=\"527\" height=\"152\" class=\"aligncenter size-full wp-image-20688\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly-2.png 527w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/01\/NET-Core-5.0-Retry-Pattern-Timeout-ve-Circuit-Breaker-Polly-2-300x87.png 300w\" sizes=\"auto, (max-width: 527px) 100vw, 527px\" \/><\/a><\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Client ve server aras\u0131ndaki haberle\u015fmede request\/response esas\u0131na dayanan bir proje d\u00fc\u015fleyelim&#8230; Client&#8217;\u0131n, ihtiyac\u0131 do\u011frultusunda server&#8217;a request tabanl\u0131 isteklerde bulunabildi\u011fini ve elde edilen response neticesinde gelen verileri i\u015fleyebildi\u011fini&#8230; Evet, biliyorum. Bu durum g\u00fcn\u00fcm\u00fcz\u00fcn en&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":20690,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2739,3102,4026,153],"tags":[4092,4091,4090,4104,4095,4097,4101,4087,4103,4105,4096,4098,4093,4102,4088,4099,4089,4086,4094,4100],"class_list":["post-20283","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-asp-net-core","category-asp-net-core-5-0","category-design-pattern","tag-net-core-retry-pattern","tag-asp-net-core-polly","tag-asp-net-core-retry-pattern","tag-circuit-breaker","tag-fault-handling-reactive-policies","tag-hata-isleme-politikalari","tag-optimistic-timeout","tag-polly","tag-polly-cancellationtoken","tag-polly-circuit-breaker","tag-polly-fault-handling-reactive-policies","tag-polly-hata-isleme-politikalari","tag-polly-library","tag-polly-optimistic-timeout","tag-polly-retry-pattern","tag-polly-timeout","tag-retry","tag-retry-pattern","tag-retry-pattern-nedir","tag-timeout"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20283","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=20283"}],"version-history":[{"count":64,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20283\/revisions"}],"predecessor-version":[{"id":20724,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20283\/revisions\/20724"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/20690"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=20283"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=20283"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=20283"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}