{"id":34246,"date":"2025-11-13T23:31:22","date_gmt":"2025-11-13T20:31:22","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/"},"modified":"2025-11-13T23:31:22","modified_gmt":"2025-11-13T20:31:22","slug":"gonun-context-paketi-dogru-kullanim-kilavuzu","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/","title":{"rendered":"Go&#8217;nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu"},"content":{"rendered":"<p><body><\/p>\n<p>Modern Go uygulamalar\u0131 geli\u015ftirirken, e\u015fzamanl\u0131l\u0131k ve hata y\u00f6netimi ka\u00e7\u0131n\u0131lmaz zorluklard\u0131r. Peki, uzun s\u00fcren bir i\u015flem devam ederken kullan\u0131c\u0131 iste\u011fini iptal etmek, veritaban\u0131 sorgusuna bir zaman a\u015f\u0131m\u0131 uygulamak veya mikroservisler aras\u0131nda i\u015flem kimli\u011fi ta\u015f\u0131mak gibi durumlar\u0131 nas\u0131l ele al\u0131rs\u0131n\u0131z? \u0130\u015fte tam bu noktada, Go&#8217;nun <code>context<\/code> paketi devreye girerek bu karma\u015f\u0131k senaryolar\u0131 zarif ve etkili bir \u015fekilde y\u00f6netmenizi sa\u011flar.<\/p>\n<p>Go, e\u015fzamanl\u0131l\u0131\u011f\u0131 goroutine&#8217;ler ve kanallar arac\u0131l\u0131\u011f\u0131yla olduk\u00e7a kolayla\u015ft\u0131r\u0131r. Ancak, bir goroutine&#8217;in ba\u015flatt\u0131\u011f\u0131 bir i\u015fi durdurma, belirli bir s\u00fcre sonra otomatik olarak iptal etme veya bir istek boyunca ge\u00e7erli olacak verileri g\u00fcvenli bir \u015fekilde aktarma ihtiyac\u0131 do\u011fdu\u011funda i\u015fler karma\u015f\u0131kla\u015fabilir. Geleneksel yakla\u015f\u0131mlar genellikle karma\u015f\u0131k kanal yap\u0131lar\u0131 veya global durumlar gerektirirken, <code>context<\/code> paketi bu t\u00fcr zorluklar i\u00e7in standartla\u015ft\u0131r\u0131lm\u0131\u015f, hafif ve g\u00fc\u00e7l\u00fc bir \u00e7\u00f6z\u00fcm sunar. \u00d6zellikle web sunucular\u0131, veritaban\u0131 i\u015flemleri veya di\u011fer uzun s\u00fcreli arka plan g\u00f6revleri gibi da\u011f\u0131t\u0131k sistemlerde, i\u015flemlerin ya\u015fam d\u00f6ng\u00fcs\u00fcn\u00fc y\u00f6netmek ve kaynak s\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00f6nlemek kritik \u00f6neme sahiptir. \u00d6rne\u011fin, bir kullan\u0131c\u0131 bir web sayfas\u0131n\u0131 kapat\u0131rsa, o istekle ilgili devam eden t\u00fcm arka plan i\u015flemlerinin de durdurulmas\u0131 performans\u0131 art\u0131r\u0131r ve gereksiz kaynak t\u00fcketimini engeller. Aksi takdirde, iptal edilmeyen goroutine&#8217;ler bellekte birikerek uygulaman\u0131z\u0131n performans\u0131n\u0131 d\u00fc\u015f\u00fcrebilir ve beklenmedik hatalara yol a\u00e7abilir. Bu nedenle, <code>context<\/code> paketi sadece kodunuzu daha okunabilir ve s\u00fcrd\u00fcr\u00fclebilir hale getirmekle kalmaz, ayn\u0131 zamanda Go uygulamalar\u0131n\u0131z\u0131n dayan\u0131kl\u0131l\u0131\u011f\u0131n\u0131 ve verimlili\u011fini de art\u0131r\u0131r.<\/p>\n<p>Bu paket, temelde d\u00f6rt ana i\u015flevi destekler:<\/p>\n<ul>\n<li><strong>\u0130ptal Sinyali Verme:<\/strong> Bir i\u015flemin veya goroutine&#8217;in harici bir olay (\u00f6rne\u011fin kullan\u0131c\u0131 iste\u011finin iptali) nedeniyle durdurulmas\u0131 gerekti\u011fini bildirme.<\/li>\n<li><strong>Zaman A\u015f\u0131m\u0131 Belirleme:<\/strong> Bir i\u015flemin belirli bir s\u00fcre i\u00e7inde tamamlanmamas\u0131 durumunda otomatik olarak iptal edilmesini sa\u011flama.<\/li>\n<li><strong>Son Tarih Belirleme:<\/strong> Bir i\u015flemin belirli bir tarih veya saate kadar tamamlanmas\u0131 gerekti\u011fini bildirme.<\/li>\n<li><strong>\u0130stek Kapsaml\u0131 Veri Aktar\u0131m\u0131:<\/strong> Bir iste\u011fin ya\u015fam d\u00f6ng\u00fcs\u00fc boyunca (\u00f6rne\u011fin bir HTTP iste\u011fi) o iste\u011fe \u00f6zg\u00fc verileri (\u00f6rne\u011fin kullan\u0131c\u0131 kimli\u011fi veya i\u015flem izleme kimli\u011fi) g\u00fcvenli bir \u015fekilde ta\u015f\u0131ma.<\/li>\n<\/ul>\n<p>Bu yetenekler sayesinde, e\u015fzamanl\u0131 \u00e7al\u0131\u015fan \u00e7ok say\u0131da goroutine&#8217;in uyumlu bir \u015fekilde i\u015f birli\u011fi yapmas\u0131 ve birbirlerini gerekti\u011finde durdurabilmesi m\u00fcmk\u00fcn olur. B\u00f6ylece uygulaman\u0131z daha kararl\u0131 hale gelir ve gereksiz yere kaynak t\u00fcketmez. K\u0131sacas\u0131, Go&#8217;da sa\u011flam ve \u00f6l\u00e7eklenebilir uygulamalar geli\u015ftirmek istiyorsan\u0131z, <code>context<\/code> paketini anlamak ve do\u011fru kullanmak temel bir gerekliliktir.<\/p>\n<h3>context.Context Nedir ve Temel \u0130\u015flevleri Nelerdir?<\/h3>\n<p><code>context.Context<\/code>, Go dilinde e\u015fzamanl\u0131 i\u015flemler aras\u0131nda iptal sinyalleri, zaman a\u015f\u0131m\u0131 bilgileri ve istek kapsaml\u0131 verileri ta\u015f\u0131yan bir aray\u00fczd\u00fcr. Asl\u0131nda, bu aray\u00fcz sadece d\u00f6rt ana metot tan\u0131mlar ve bu metotlar\u0131n her biri belirli bir amaca hizmet eder. Bu aray\u00fcz\u00fcn basitli\u011fi, onun esnekli\u011fini ve Go ekosistemindeki yayg\u0131n kabul\u00fcn\u00fc a\u00e7\u0131klar. Her <code>Context<\/code>, bir a\u011fa\u00e7 yap\u0131s\u0131ndaki d\u00fc\u011f\u00fcm gibidir; bir <code>Context<\/code>&#8216;ten t\u00fcretilen (child) di\u011fer <code>Context<\/code>&#8216;ler, ebeveynlerinin \u00f6zelliklerini miras al\u0131r ve ebeveyn iptal edildi\u011finde otomatik olarak iptal olurlar.<\/p>\n<p><code>context.Context<\/code> aray\u00fcz\u00fcn\u00fcn metotlar\u0131 \u015funlard\u0131r:<\/p>\n<ul>\n<li>\n      <code>Done() <-chan struct{}<\/code>: Bu metot, context iptal edildi\u011finde veya zaman a\u015f\u0131m\u0131na u\u011frad\u0131\u011f\u0131nda kapanan bir kanal d\u00f6nd\u00fcr\u00fcr. Goroutine'ler bu kanal\u0131 dinleyerek iptal sinyalini alabilir ve i\u015flerini temiz bir \u015fekilde durdurabilirler. Kanal\u0131n kapanmas\u0131, bir olay\u0131n ger\u00e7ekle\u015fti\u011fini g\u00f6steren yayg\u0131n bir Go modelidir.\n    <\/li>\n<li>\n      <code>Err() error<\/code>: <code>Done()<\/code> kanal\u0131 kapand\u0131\u011f\u0131nda, bu metot context'in neden iptal edildi\u011fini (\u00f6rne\u011fin, <code>context.Canceled<\/code> veya <code>context.DeadlineExceeded<\/code>) belirten bir hata d\u00f6nd\u00fcr\u00fcr. Bu hata, i\u015flemin hangi ko\u015fullar alt\u0131nda durduruldu\u011funu anlamak i\u00e7in \u00f6nemlidir.\n    <\/li>\n<li>\n      <code>Deadline() (deadline time.Time, ok bool)<\/code>: Bu metot, context'in bir zaman a\u015f\u0131m\u0131 veya son tarih ile yap\u0131land\u0131r\u0131l\u0131p yap\u0131land\u0131r\u0131lmad\u0131\u011f\u0131n\u0131 ve yap\u0131land\u0131r\u0131ld\u0131ysa ne zaman sona erece\u011fini belirtir. E\u011fer bir son tarih tan\u0131mlanm\u0131\u015fsa <code>ok<\/code> de\u011feri <code>true<\/code> olur ve <code>deadline<\/code> de\u011feri de set edilmi\u015f olur.\n    <\/li>\n<li>\n      <code>Value(key any) any<\/code>: Bu metot, context ile ili\u015fkili istek kapsaml\u0131 veriye eri\u015fim sa\u011flar. Veriler anahtar-de\u011fer \u00e7iftleri \u015feklinde saklan\u0131r ve genellikle tracing ID'leri, yetkilendirme token'lar\u0131 veya di\u011fer iste\u011fe \u00f6zg\u00fc meta verileri ta\u015f\u0131mak i\u00e7in kullan\u0131l\u0131r. Bu metot, de\u011ferin var olup olmad\u0131\u011f\u0131n\u0131 kontrol etmek i\u00e7in <code>nil<\/code> d\u00f6nd\u00fcrebilir.\n    <\/li>\n<\/ul>\n<p><code>context<\/code> paketi, bu temel aray\u00fcz etraf\u0131nda \u00e7e\u015fitli t\u00fcretilmi\u015f <code>Context<\/code>'ler olu\u015fturmak i\u00e7in fonksiyonlar sunar. Bu fonksiyonlar, k\u00f6k <code>Context<\/code>'lerden (<code>context.Background()<\/code> ve <code>context.TODO()<\/code>) ba\u015flayarak, iptal edilebilir, zaman a\u015f\u0131m\u0131 olan veya de\u011fer ta\u015f\u0131yan <code>Context<\/code>'ler yarat\u0131r. Bu hiyerar\u015fik yap\u0131, da\u011f\u0131t\u0131k sistemlerde bir iste\u011fin ba\u015flang\u0131c\u0131ndan sonuna kadar t\u00fcm ilgili i\u015flemlerin kolayca izlenmesini ve y\u00f6netilmesini sa\u011flar. Ayr\u0131ca, <code>context<\/code> paketinin sa\u011flad\u0131\u011f\u0131 temiz API sayesinde, kodunuz daha az hata e\u011filimli ve daha anla\u015f\u0131l\u0131r hale gelir, b\u00f6ylece ekip \u00fcyeleri aras\u0131nda i\u015fbirli\u011fi de kolayla\u015f\u0131r.<\/p>\n<h2>context Paketi Temelleri: Hangi Fonksiyonlar\u0131 Bilmeliyiz?<\/h2>\n<p><code>context<\/code> paketinin g\u00fcc\u00fcn\u00fc kullanmak i\u00e7in bilmeniz gereken birka\u00e7 temel fonksiyon bulunmaktad\u0131r. Bu fonksiyonlar, farkl\u0131 ihtiya\u00e7lara y\u00f6nelik olarak <code>Context<\/code> nesneleri olu\u015fturman\u0131za olanak tan\u0131r ve Go uygulamalar\u0131n\u0131z\u0131n e\u015fzamanl\u0131l\u0131k y\u00f6netimini bir \u00fcst seviyeye ta\u015f\u0131r. Her bir fonksiyon, belirli bir senaryoyu ele almak \u00fczere tasarlanm\u0131\u015ft\u0131r ve do\u011fru yerde do\u011fru fonksiyonu kullanmak, kodunuzun performans\u0131n\u0131 ve g\u00fcvenilirli\u011fini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r. A\u015fa\u011f\u0131da, bu temel fonksiyonlar\u0131 ve kullan\u0131m ama\u00e7lar\u0131n\u0131 detayl\u0131ca inceleyelim.<\/p>\n<h3><code>context.Background()<\/code> ve <code>context.TODO()<\/code>: Ba\u015flang\u0131\u00e7 Noktalar\u0131<\/h3>\n<p>Her Go uygulamas\u0131nda, <code>context<\/code> hiyerar\u015fisinin bir ba\u015flang\u0131\u00e7 noktas\u0131 olmas\u0131 gerekir. \u0130\u015fte bu noktada <code>context.Background()<\/code> ve <code>context.TODO()<\/code> devreye girer. Her ikisi de temelde bo\u015f bir <code>Context<\/code> d\u00f6nd\u00fcrse de, kullan\u0131m ama\u00e7lar\u0131 farkl\u0131d\u0131r ve do\u011fru se\u00e7imi yapmak, kodunuzun niyetini a\u00e7\u0131k\u00e7a belirtmenize yard\u0131mc\u0131 olur.<\/p>\n<ul>\n<li>\n      <strong><code>context.Background()<\/code>:<\/strong> Bu, Go uygulaman\u0131z\u0131n ana <code>Context<\/code>'idir. Genellikle, belirli bir ya\u015fam d\u00f6ng\u00fcs\u00fcne veya iste\u011fe ba\u011fl\u0131 olmayan, program\u0131n ana goroutine'inden veya testlerden ba\u015flayan t\u00fcm \u00e7a\u011fr\u0131larda kullan\u0131l\u0131r. \u00d6rne\u011fin, uygulaman\u0131z ba\u015flad\u0131\u011f\u0131nda tek seferlik bir ba\u015flang\u0131\u00e7 i\u015flevi \u00e7a\u011f\u0131r\u0131yorsan\u0131z veya bir goroutine'i tamamen ba\u011f\u0131ms\u0131z \u00e7al\u0131\u015ft\u0131rmak istiyorsan\u0131z bu <code>Context<\/code>'i kullan\u0131rs\u0131n\u0131z. \u0130ptal edilemez, zaman a\u015f\u0131m\u0131 yoktur ve herhangi bir de\u011fer ta\u015f\u0131maz. Genellikle, bir <code>Context<\/code>'e ihtiya\u00e7 duydu\u011funuz ancak daha spesifik bir gereksiniminiz olmad\u0131\u011f\u0131nda iyi bir varsay\u0131lan se\u00e7imdir.<\/p>\n<pre><code>\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc main() {\n\t\/\/ context.Background() ile ba\u011f\u0131ms\u0131z bir i\u015flem ba\u015flatma\n\tctx := context.Background()\n\n\tselect {\n\tcase <-ctx.Done():\n\t\tfmt.Println(\"Bu context asla iptal olmaz (Background)\")\n\tcase <-time.After(1 * time.Second):\n\t\tfmt.Println(\"1 saniye ge\u00e7ti, Background context hala aktif.\")\n\t}\n}\n      <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n      <strong><code>context.TODO()<\/code>:<\/strong> Bu fonksiyonun ismi, geli\u015ftiriciye \"yap\u0131lacaklar listesinde\" oldu\u011funu hat\u0131rlat\u0131r. Yani, hen\u00fcz net bir <code>Context<\/code>'in ne olmas\u0131 gerekti\u011fine karar vermedi\u011finizde, ancak yine de bir <code>Context<\/code> parametresi gerektiren bir fonksiyonu \u00e7a\u011f\u0131rman\u0131z gerekti\u011finde ge\u00e7ici olarak kullan\u0131l\u0131r. Genellikle kodda bir yer tutucu olarak i\u015flev g\u00f6r\u00fcr ve daha sonra uygun bir <code>Context<\/code> ile de\u011fi\u015ftirilmesi beklenir. E\u011fer bir <code>Context<\/code>'e ihtiyac\u0131n\u0131z varsa fakat \"ne kullanaca\u011f\u0131m\u0131 bilmiyorum\" diyorsan\u0131z <code>context.TODO()<\/code> kullanmak, kodunuzu okuyan di\u011fer geli\u015ftiricilere burada bir iyile\u015ftirme veya tasar\u0131m karar\u0131 bekledi\u011finizi bildirir. T\u0131pk\u0131 <code>Background()<\/code> gibi, bu <code>Context<\/code> de iptal edilemez, zaman a\u015f\u0131m\u0131 yoktur ve de\u011fer ta\u015f\u0131maz.<\/p>\n<pre><code>\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc doSomething(ctx context.Context) {\n\tselect {\n\tcase <-ctx.Done():\n\t\tfmt.Println(\"\u0130\u015flem iptal edildi:\", ctx.Err())\n\tcase <-time.After(500 * time.Millisecond):\n\t\tfmt.Println(\"Do something completed.\")\n\t}\n}\n\nfunc main() {\n\t\/\/ Geli\u015ftirme a\u015famas\u0131nda ge\u00e7ici olarak context.TODO() kullanma\n\tfmt.Println(\"context.TODO() ile bir i\u015flem ba\u015flat\u0131l\u0131yor...\")\n\tdoSomething(context.TODO())\n\ttime.Sleep(1 * time.Second) \/\/ \u0130\u015flemin tamamlanmas\u0131 i\u00e7in bekle\n}\n      <\/pre>\n<p><\/code>\n    <\/li>\n<\/ul>\n<div class=\"expert-tip\">\n    Uzman \u0130pucu: <code>context.TODO()<\/code>'yu sadece k\u0131sa s\u00fcreli, ge\u00e7ici \u00e7\u00f6z\u00fcmler i\u00e7in kullan\u0131n. M\u00fcmk\u00fcn olan her yerde <code>context.Background()<\/code> veya daha spesifik, t\u00fcretilmi\u015f bir <code>Context<\/code> kullanmay\u0131 tercih edin. Bu, kodunuzun niyetini netle\u015ftirir ve potansiyel hatalar\u0131 \u00f6nler.\n  <\/div>\n<p>Her iki fonksiyon da temel olarak ayn\u0131 bo\u015f <code>Context<\/code>'i d\u00f6nd\u00fcrse de, aralar\u0131ndaki fark niyetlerindedir. <code>Background()<\/code> uygulaman\u0131n k\u00f6k\u00fc i\u00e7in bilin\u00e7li bir se\u00e7imken, <code>TODO()<\/code> bir yer tutucudur ve gelecekteki bir iyile\u015ftirmeyi i\u015faret eder. Bu ayr\u0131m\u0131 anlamak, Go projelerinizde daha anlaml\u0131 ve bak\u0131m\u0131 kolay kod yazman\u0131za yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<h3>\u0130ptal Mekanizmalar\u0131: <code>WithCancel<\/code> ile Nas\u0131l \u00c7al\u0131\u015f\u0131l\u0131r?<\/h3>\n<p><code>context.WithCancel<\/code> fonksiyonu, bir <code>Context<\/code> hiyerar\u015fisinde manuel olarak iptal edilebilen yeni bir <code>Context<\/code> olu\u015fturman\u0131z\u0131 sa\u011flar. Bu, uzun s\u00fcreli bir i\u015flem \u00e7al\u0131\u015f\u0131rken, harici bir olay (\u00f6rne\u011fin kullan\u0131c\u0131 aray\u00fcz\u00fcnden bir iptal d\u00fc\u011fmesine bas\u0131lmas\u0131 veya bir HTTP iste\u011finin ba\u011flant\u0131s\u0131n\u0131n kesilmesi) nedeniyle o i\u015flemin durdurulmas\u0131 gerekti\u011finde son derece kullan\u0131\u015fl\u0131d\u0131r. <code>WithCancel<\/code> fonksiyonu iki de\u011fer d\u00f6nd\u00fcr\u00fcr: yeni t\u00fcretilmi\u015f <code>Context<\/code> ve bir <code>CancelFunc<\/code>. <code>CancelFunc<\/code> \u00e7a\u011fr\u0131ld\u0131\u011f\u0131nda, t\u00fcretilmi\u015f <code>Context<\/code> ve ondan daha da t\u00fcretilmi\u015f t\u00fcm <code>Context<\/code>'ler iptal sinyali al\u0131r.<\/p>\n<pre><code>\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc performTask(ctx context.Context, taskID int) {\n\tfmt.Printf(\"G\u00f6rev %d ba\u015flad\u0131...\\n\", taskID)\n\tselect {\n\tcase <-time.After(2 * time.Second):\n\t\tfmt.Printf(\"G\u00f6rev %d tamamland\u0131.\\n\", taskID)\n\tcase <-ctx.Done():\n\t\t\/\/ Context iptal edildi\u011finde buras\u0131 tetiklenir\n\t\tfmt.Printf(\"G\u00f6rev %d iptal edildi: %v\\n\", taskID, ctx.Err())\n\t}\n}\n\nfunc main() {\n\t\/\/ context.Background()'dan yeni bir iptal edilebilir context t\u00fcret\n\tctx, cancel := context.WithCancel(context.Background())\n\tdefer cancel() \/\/ main fonksiyonu sona erdi\u011finde cancel'\u0131 \u00e7a\u011f\u0131r\n\n\tgo performTask(ctx, 1)\n\n\tfmt.Println(\"1 saniye sonra g\u00f6rev 1'i iptal et.\")\n\ttime.Sleep(1 * time.Second)\n\n\t\/\/ Context'i iptal et\n\tcancel()\n\n\t\/\/ Biraz bekleyelim ki goroutine \u00e7\u0131kt\u0131s\u0131n\u0131 g\u00f6relim\n\ttime.Sleep(500 * time.Millisecond)\n\n\t\/\/ Yeni bir g\u00f6rev ba\u015flat ama hemen iptal et\n\tctx2, cancel2 := context.WithCancel(ctx) \/\/ iptal edilmi\u015f ctx'ten t\u00fcretmek hemen iptal eder\n\tdefer cancel2()\n\tgo performTask(ctx2, 2)\n\tfmt.Println(\"G\u00f6rev 2 hemen iptal edildi \u00e7\u00fcnk\u00fc ebeveyni iptaldi.\")\n\ttime.Sleep(100 * time.Millisecond)\n}\n  <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki \u00f6rnekte, <code>performTask<\/code> ad\u0131nda uzun s\u00fcren bir i\u015flevi temsil eden bir goroutine ba\u015flat\u0131yoruz. Bu goroutine, i\u015fini 2 saniyede bitirmeyi dener ancak ayn\u0131 zamanda <code>ctx.Done()<\/code> kanal\u0131n\u0131 da dinler. <code>main<\/code> fonksiyonunda 1 saniye bekledikten sonra <code>cancel()<\/code> fonksiyonunu \u00e7a\u011f\u0131rarak <code>ctx<\/code>'i iptal ederiz. Bu durum, <code>performTask<\/code> i\u00e7indeki <code>select<\/code> blo\u011funun <code><-ctx.Done()<\/code> durumunu tetiklemesine ve g\u00f6revin erken sonland\u0131r\u0131lmas\u0131na neden olur. <code>defer cancel()<\/code> kullan\u0131m\u0131, kaynak s\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00f6nlemek i\u00e7in kritik \u00f6neme sahiptir; \u00e7\u00fcnk\u00fc <code>CancelFunc<\/code> \u00e7a\u011fr\u0131lmad\u0131\u011f\u0131nda, <code>Context<\/code> ile ili\u015fkili goroutine'ler bellekte kalabilir ve gereksiz yere kaynak t\u00fcketebilir. \u0130kinci \u00f6rnekte ise, zaten iptal edilmi\u015f bir <code>Context<\/code>'ten t\u00fcretilen bir <code>Context<\/code>'in otomatik olarak iptal oldu\u011funu g\u00f6sterdik, bu da hiyerar\u015fik yap\u0131n\u0131n nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 vurgular.<\/p>\n<div class=\"expert-tip\">\n    Uzman \u0130pucu: Her <code>WithCancel<\/code>, <code>WithTimeout<\/code> veya <code>WithDeadline<\/code> \u00e7a\u011fr\u0131s\u0131, e\u015flik eden bir <code>CancelFunc<\/code> d\u00f6nd\u00fcr\u00fcr. Bu <code>CancelFunc<\/code>'i <strong>her zaman<\/strong> uygun bir zamanda \u00e7a\u011f\u0131rd\u0131\u011f\u0131n\u0131zdan emin olun, genellikle bir <code>defer<\/code> ifadesiyle. Aksi takdirde, <code>Context<\/code> a\u011fac\u0131nda kaynak s\u0131z\u0131nt\u0131lar\u0131na yol a\u00e7abilirsiniz, bu da uzun \u00f6m\u00fcrl\u00fc Go uygulamalar\u0131nda ciddi performans sorunlar\u0131na neden olabilir.\n  <\/div>\n<h3>Zaman S\u0131n\u0131rlar\u0131 Belirleme: <code>WithTimeout<\/code> ve <code>WithDeadline<\/code> Fark\u0131 Nedir?<\/h3>\n<p>Go'da e\u015fzamanl\u0131 i\u015flemlerde zaman y\u00f6netimi kritik bir konudur. Bir i\u015flemin \u00e7ok uzun s\u00fcrmesi, sistem kaynaklar\u0131n\u0131 t\u00fcketebilir ve kullan\u0131c\u0131 deneyimini olumsuz etkileyebilir. <code>context<\/code> paketi, bu t\u00fcr senaryolar i\u00e7in <code>WithTimeout<\/code> ve <code>WithDeadline<\/code> fonksiyonlar\u0131n\u0131 sunar. Her ikisi de belirli bir s\u00fcre sonra <code>Context<\/code>'in otomatik olarak iptal edilmesini sa\u011flar, ancak kullan\u0131m bi\u00e7imleri aras\u0131nda \u00f6nemli bir fark vard\u0131r.<\/p>\n<ul>\n<li>\n      <strong><code>context.WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)<\/code>:<\/strong><br \/>\n      Bu fonksiyon, belirli bir <code>time.Duration<\/code> (\u00f6rne\u011fin 5 saniye, 300 milisaniye) sonra otomatik olarak iptal olacak bir <code>Context<\/code> olu\u015fturur. Kullan\u0131m\u0131 kolayd\u0131r ve genellikle belirli bir i\u015flem i\u00e7in maksimum izin verilen s\u00fcreyi tan\u0131mlaman\u0131z gerekti\u011finde tercih edilir. \u00d6rne\u011fin, bir HTTP iste\u011fi g\u00f6nderirken veya bir veritaban\u0131 sorgusu yaparken belirli bir yan\u0131t s\u00fcresi bekliyorsan\u0131z idealdir.<\/p>\n<pre><code>\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc longRunningOperation(ctx context.Context, id int) {\n\tfmt.Printf(\"Operasyon %d ba\u015flad\u0131...\\n\", id)\n\tselect {\n\tcase <-time.After(3 * time.Second):\n\t\tfmt.Printf(\"Operasyon %d tamamland\u0131.\\n\", id)\n\tcase <-ctx.Done():\n\t\tfmt.Printf(\"Operasyon %d zaman a\u015f\u0131m\u0131na u\u011frad\u0131 veya iptal edildi: %v\\n\", id, ctx.Err())\n\t}\n}\n\nfunc main() {\n\t\/\/ 2 saniyelik zaman a\u015f\u0131m\u0131 ile bir context olu\u015ftur\n\tctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)\n\tdefer cancel()\n\n\tgo longRunningOperation(ctx, 1)\n\n\tfmt.Println(\"Ana fonksiyon bekliyor...\")\n\ttime.Sleep(3 * time.Second) \/\/ longRunningOperation'dan daha uzun bekle\n}\n      <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki \u00f6rnekte, <code>longRunningOperation<\/code> normalde 3 saniye s\u00fcrerdi, ancak <code>ctx<\/code>'e 2 saniyelik bir zaman a\u015f\u0131m\u0131 uygulad\u0131k. Bu nedenle, 2 saniye sonra <code>ctx.Done()<\/code> kanal\u0131 kapanacak ve operasyon zaman a\u015f\u0131m\u0131 hatas\u0131yla erken sonland\u0131r\u0131lacakt\u0131r.<\/p>\n<\/li>\n<li>\n      <strong><code>context.WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)<\/code>:<\/strong><br \/>\n      Bu fonksiyon, belirli bir mutlak zaman noktas\u0131na (<code>time.Time<\/code>) kadar ge\u00e7erli olacak bir <code>Context<\/code> olu\u015fturur. Yani, \"bu i\u015flem \u015fu saate kadar bitmeli\" demek istedi\u011finizde kullan\u0131l\u0131r. \u00d6rne\u011fin, bir hizmetin SLA's\u0131 (Hizmet Seviyesi Anla\u015fmas\u0131) nedeniyle belirli bir mutlak son tarihe uyman\u0131z gerekti\u011finde veya sistem genelindeki bir zaman \u00e7izelgesine g\u00f6re i\u015flemlerinizi ayarlaman\u0131z gerekti\u011finde tercih edilebilir.<\/p>\n<pre><code>\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc fetchData(ctx context.Context, source string) {\n\tfmt.Printf(\"Veri \u00e7ekme i\u015flemi '%s' ba\u015flad\u0131...\\n\", source)\n\tselect {\n\tcase <-time.After(1500 * time.Millisecond):\n\t\tfmt.Printf(\"Veri \u00e7ekme i\u015flemi '%s' tamamland\u0131.\\n\", source)\n\tcase <-ctx.Done():\n\t\tfmt.Printf(\"Veri \u00e7ekme i\u015flemi '%s' son tarihe ula\u015f\u0131ld\u0131\u011f\u0131 i\u00e7in iptal edildi: %v\\n\", source, ctx.Err())\n\t}\n}\n\nfunc main() {\n\t\/\/ \u015eu andan 1 saniye sonraki bir son tarih belirle\n\tdeadline := time.Now().Add(1 * time.Second)\n\tctx, cancel := context.WithDeadline(context.Background(), deadline)\n\tdefer cancel()\n\n\tgo fetchData(ctx, \"Uzak API\")\n\n\tfmt.Println(\"Ana fonksiyon son tarihi bekliyor...\")\n\ttime.Sleep(1200 * time.Millisecond) \/\/ Biraz son tarihten sonra bekleyelim\n}\n      <\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>fetchData<\/code> i\u015flemi normalde 1.5 saniye s\u00fcrer, ancak <code>ctx<\/code>'i \u015fu anki zamandan 1 saniye sonraki bir son tarihle ayarlad\u0131k. Bu durumda, <code>fetchData<\/code> operasyonu tamamlanmadan son tarihe ula\u015f\u0131lacak ve i\u015flem erken iptal edilecektir.<\/p>\n<\/li>\n<\/ul>\n<div class=\"expert-tip\">\n    Uzman \u0130pucu: <code>WithTimeout<\/code> genellikle daha yayg\u0131n kullan\u0131l\u0131r \u00e7\u00fcnk\u00fc g\u00f6reli bir s\u00fcre (\u00f6rne\u011fin \"\u015fimdi'den 5 saniye sonra\") belirlemek daha sezgiseld\u0131r. <code>WithDeadline<\/code> ise daha \u00e7ok belirli bir mutlak zaman noktas\u0131na ba\u011f\u0131ml\u0131 i\u015flemlerde tercih edilir. \u0130kisini bir arada kullanmak, en kat\u0131 olan\u0131n ge\u00e7erli olaca\u011f\u0131 anlam\u0131na gelir. \u00d6rne\u011fin, hem 10 saniyelik bir zaman a\u015f\u0131m\u0131n\u0131z hem de TS\u0130 23:59:59'luk bir son tarihiniz varsa, hangisi \u00f6nce gelirse <code>Context<\/code> o zaman iptal olur.\n  <\/div>\n<p>Her iki fonksiyon da bir <code>CancelFunc<\/code> d\u00f6nd\u00fcr\u00fcr ve bu fonksiyonun da <code>defer<\/code> ile \u00e7a\u011fr\u0131lmas\u0131, yukar\u0131da bahsedildi\u011fi gibi kaynak s\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00f6nlemek ad\u0131na hayati \u00f6neme sahiptir. Bu fonksiyonlar\u0131 do\u011fru bir \u015fekilde kullanarak, Go uygulamalar\u0131n\u0131zda e\u015fzamanl\u0131 i\u015flemlerin zaman\u0131nda tamamlanmas\u0131n\u0131 sa\u011flayabilir, aksi takdirde olu\u015fabilecek blokajlar\u0131 ve performans d\u00fc\u015f\u00fc\u015flerini engelleyebilirsiniz. \u00d6zellikle uzun s\u00fcreli a\u011f \u00e7a\u011fr\u0131lar\u0131 veya yo\u011fun CPU kullanan hesaplamalar i\u00e7in bu mekanizmalar vazge\u00e7ilmezdir.<\/p>\n<h2>Ger\u00e7ek D\u00fcnya Senaryolar\u0131: context ile Yayg\u0131n Problemleri Nas\u0131l \u00c7\u00f6zeriz?<\/h2>\n<p><code>context<\/code> paketi, Go'daki bir\u00e7ok ger\u00e7ek d\u00fcnya probleminin \u00e7\u00f6z\u00fcm\u00fcnde merkezi bir rol oynar. Bu b\u00f6l\u00fcm, paketin pratik uygulamalar\u0131n\u0131 vaka analizleri ile detayland\u0131racak ve g\u00fcnl\u00fck geli\u015ftirme s\u00fcre\u00e7lerinizde kar\u015f\u0131la\u015fabilece\u011finiz yayg\u0131n senaryolarda <code>context<\/code>'i nas\u0131l kullanman\u0131z gerekti\u011fini g\u00f6sterecektir. Da\u011f\u0131t\u0131k sistemlerden veritaban\u0131 i\u015flemlerine kadar geni\u015f bir yelpazede, <code>context<\/code> do\u011fru kullan\u0131ld\u0131\u011f\u0131nda kodunuzu daha sa\u011flam, \u00f6l\u00e7eklenebilir ve hata toleransl\u0131 hale getirir.<\/p>\n<h3>HTTP \u0130steklerinde Ya\u015fam D\u00f6ng\u00fcs\u00fc Y\u00f6netimi Nas\u0131l Yap\u0131l\u0131r?<\/h3>\n<p>Web sunucular\u0131, \u00f6zellikle API geli\u015ftirmede, genellikle bir\u00e7ok e\u015fzamanl\u0131 iste\u011fi i\u015fler. Her bir gelen HTTP iste\u011fi, kendi ya\u015fam d\u00f6ng\u00fcs\u00fcne sahiptir ve bu ya\u015fam d\u00f6ng\u00fcs\u00fc boyunca \u00e7e\u015fitli arka plan i\u015flemleri (veritaban\u0131 sorgular\u0131, di\u011fer mikroservis \u00e7a\u011fr\u0131lar\u0131 vb.) tetiklenebilir. E\u011fer istemci ba\u011flant\u0131y\u0131 kapat\u0131rsa veya istek zaman a\u015f\u0131m\u0131na u\u011frarsa, sunucunun o istekle ilgili t\u00fcm devam eden i\u015flemleri durdurmas\u0131 gerekir. Aksi takdirde, gereksiz hesaplama ve kaynak t\u00fcketimi ya\u015fan\u0131r.<\/p>\n<p>Go'nun <code>net\/http<\/code> paketi, her gelen istekle (<code>*http.Request<\/code>) birlikte otomatik olarak bir <code>Context<\/code> sa\u011flar. Bu <code>Context<\/code>, istemci ba\u011flant\u0131s\u0131 kesildi\u011finde veya HTTP sunucusunun kendi zaman a\u015f\u0131m\u0131 ayarlar\u0131na g\u00f6re otomatik olarak iptal olur. Bu \u00f6zelli\u011fi kullanarak, istekle ilgili t\u00fcm a\u015fa\u011f\u0131 ak\u0131\u015f i\u015flemlerini kolayca y\u00f6netebilirsiniz.<\/p>\n<pre><code>\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"net\/http\"\n\t\"time\"\n)\n\n\/\/ simulateDBQuery uzun s\u00fcren bir veritaban\u0131 sorgusunu taklit eder\nfunc simulateDBQuery(ctx context.Context, userID string) (string, error) {\n\tselect {\n\tcase <-time.After(3 * time.Second): \/\/ Normalde 3 saniye s\u00fcrer\n\t\treturn fmt.Sprintf(\"Kullan\u0131c\u0131 %s i\u00e7in veriler al\u0131nd\u0131.\", userID), nil\n\tcase <-ctx.Done():\n\t\t\/\/ Context iptal edildi\u011finde veya zaman a\u015f\u0131m\u0131na u\u011frad\u0131\u011f\u0131nda\n\t\treturn \"\", fmt.Errorf(\"DB sorgusu iptal edildi: %v\", ctx.Err())\n\t}\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\t\/\/ \u0130stek context'ini al\u0131yoruz\n\tctx := r.Context()\n\n\t\/\/ Opsiyonel: \u0130stek context'ine ek bir zaman a\u015f\u0131m\u0131 ekleyebiliriz\n\t\/\/ (\u00f6rne\u011fin, bu handler \u00f6zelinde daha k\u0131sa bir zaman a\u015f\u0131m\u0131 istiyorsak)\n\tctx, cancel := context.WithTimeout(ctx, 2*time.Second)\n\tdefer cancel() \/\/ CancelFunc'\u0131 \u00e7a\u011f\u0131rmay\u0131 unutmay\u0131n!\n\n\tuserID := r.URL.Query().Get(\"user_id\")\n\tif userID == \"\" {\n\t\tuserID = \"varsayilan_kullanici\"\n\t}\n\n\tlog.Printf(\"\u0130stek ba\u015flad\u0131, user_id: %s\", userID)\n\n\tdata, err := simulateDBQuery(ctx, userID)\n\tif err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\tlog.Printf(\"\u0130stek tamamlanamad\u0131, user_id: %s, hata: %v\", userID, err)\n\t\treturn\n\t}\n\n\tfmt.Fprintf(w, \"API Yan\u0131t\u0131: %s\\n\", data)\n\tlog.Printf(\"\u0130stek tamamland\u0131, user_id: %s\", userID)\n}\n\nfunc main() {\n\thttp.HandleFunc(\"\/data\", handler)\n\n\t\/\/ Sunucuya varsay\u0131lan bir okuma zaman a\u015f\u0131m\u0131 (read timeout) ekleyebiliriz\n\tserver := &#038;http.Server{\n\t\tAddr:         \":8080\",\n\t\tReadTimeout:  5 * time.Second, \/\/ \u0130stemcinin iste\u011fi g\u00f6nderme s\u00fcresi\n\t\tWriteTimeout: 5 * time.Second, \/\/ Sunucunun yan\u0131t\u0131 yazma s\u00fcresi\n\t\tIdleTimeout:  10 * time.Second,\n\t}\n\n\tlog.Println(\"Sunucu 8080 portunda dinlemede...\")\n\tif err := server.ListenAndServe(); err != nil &#038;&#038; err != http.ErrServerClosed {\n\t\tlog.Fatalf(\"Sunucu ba\u015flat\u0131l\u0131rken hata olu\u015ftu: %v\", err)\n\t}\n}\n  <\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>handler<\/code> fonksiyonu gelen HTTP iste\u011finin <code>Context<\/code>'ini al\u0131r ve bunu <code>simulateDBQuery<\/code> fonksiyonuna iletir. E\u011fer istemci 2 saniye i\u00e7inde yan\u0131t alamazsa (<code>WithTimeout<\/code> nedeniyle) veya ba\u011flant\u0131y\u0131 kapat\u0131rsa, <code>simulateDBQuery<\/code> otomatik olarak iptal sinyali al\u0131r ve veritaban\u0131 sorgusunu durdurur. Bu yakla\u015f\u0131m, sistem kaynaklar\u0131n\u0131 korur ve istemciye zaman\u0131nda geri bildirim sa\u011flar. Ayn\u0131 zamanda, <code>context<\/code> paketi sayesinde, bir iste\u011fin ya\u015fam d\u00f6ng\u00fcs\u00fc boyunca belirli verileri (\u00f6rne\u011fin kullan\u0131c\u0131 kimli\u011fi, izleme kimli\u011fi) g\u00fcvenli bir \u015fekilde aktarmak i\u00e7in <code>context.WithValue<\/code> de kullan\u0131labilir. Bu, hata ay\u0131klama ve izleme yeteneklerini \u00f6nemli \u00f6l\u00e7\u00fcde geli\u015ftirir. \u00d6rne\u011fin, her iste\u011fe benzersiz bir izleme kimli\u011fi atay\u0131p bunu <code>Context<\/code> arac\u0131l\u0131\u011f\u0131yla t\u00fcm a\u015fa\u011f\u0131 ak\u0131\u015f servislere iletebilirsiniz, b\u00f6ylece bir hata durumunda t\u00fcm ilgili loglar\u0131 kolayca ili\u015fkilendirebilirsiniz.<\/p>\n<h3>Veritaban\u0131 ve Uzun S\u00fcreli \u0130\u015flemlerde context'in Rol\u00fc Nedir?<\/h3>\n<p>Veritaban\u0131 i\u015flemleri, \u00f6zellikle yo\u011fun y\u00fck alt\u0131nda veya yava\u015f a\u011f ba\u011flant\u0131lar\u0131nda, bazen beklenenden daha uzun s\u00fcrebilir. Bu durum, uygulaman\u0131n blokaj\u0131na, ba\u011flant\u0131 havuzlar\u0131n\u0131n t\u00fckenmesine ve nihayetinde hizmet kesintilerine yol a\u00e7abilir. <code>context<\/code> paketi, bu t\u00fcr sorunlar\u0131 ele almak i\u00e7in etkili bir mekanizma sunar. Go'daki \u00e7o\u011fu veritaban\u0131 s\u00fcr\u00fcc\u00fcs\u00fc (<code>database\/sql<\/code> paketi arac\u0131l\u0131\u011f\u0131yla), sorgu veya i\u015flem metotlar\u0131na bir <code>Context<\/code> parametresi kabul eder. Bu, veritaban\u0131 i\u015flemlerine zaman a\u015f\u0131m\u0131 veya iptal yetenekleri eklemenizi sa\u011flar.<\/p>\n<pre><code>\npackage main\n\nimport (\n\t\"context\"\n\t\"database\/sql\"\n\t\"fmt\"\n\t\"log\"\n\t\"time\"\n\n\t_ \"github.com\/mattn\/go-sqlite3\" \/\/ \u00d6rnek i\u00e7in bir SQLite s\u00fcr\u00fcc\u00fcs\u00fc\n)\n\n\/\/ setupDBContext, veritaban\u0131 ba\u011flant\u0131 havuzu ve context ile ilgili ayarlar\u0131 g\u00f6sterir.\nfunc setupDBContext() *sql.DB {\n\tdb, err := sql.Open(\"sqlite3\", \":memory:\") \/\/ Bellek i\u00e7i SQLite veritaban\u0131\n\tif err != nil {\n\t\tlog.Fatalf(\"Veritaban\u0131 a\u00e7\u0131lamad\u0131: %v\", err)\n\t}\n\n\t\/\/ Tablo olu\u015ftur\n\t_, err = db.Exec(\"CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Tablo olu\u015fturulamad\u0131: %v\", err)\n\t}\n\treturn db\n}\n\nfunc getUserByID(ctx context.Context, db *sql.DB, id int) (string, error) {\n\tvar name string\n\t\/\/ Context'i sorgu metoduna iletiyoruz\n\t\/\/ Veritaban\u0131 s\u00fcr\u00fcc\u00fcs\u00fc, context'in iptal edildi\u011fini alg\u0131lad\u0131\u011f\u0131nda sorguyu iptal edebilir.\n\terr := db.QueryRowContext(ctx, \"SELECT name FROM users WHERE id = ?\", id).Scan(&name)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"kullan\u0131c\u0131 ID %d sorgulan\u0131rken hata: %v\", id, err)\n\t}\n\treturn name, nil\n}\n\nfunc insertUser(ctx context.Context, db *sql.DB, id int, name, email string) error {\n\t_, err := db.ExecContext(ctx, \"INSERT INTO users (id, name, email) VALUES (?, ?, ?)\", id, name, email)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"kullan\u0131c\u0131 eklenirken hata: %v\", err)\n\t}\n\treturn nil\n}\n\nfunc main() {\n\tdb := setupDBContext()\n\tdefer db.Close()\n\n\t\/\/ Bir kullan\u0131c\u0131 ekleyelim\n\terr := insertUser(context.Background(), db, 1, \"Alice\", \"alice@example.com\")\n\tif err != nil {\n\t\tlog.Fatalf(\"Kullan\u0131c\u0131 ekleme hatas\u0131: %v\", err)\n\t}\n\n\t\/\/ 1. senaryo: Ba\u015far\u0131l\u0131 sorgu\n\tctx1, cancel1 := context.WithTimeout(context.Background(), 5*time.Second)\n\tdefer cancel1()\n\tuserName, err := getUserByID(ctx1, db, 1)\n\tif err != nil {\n\t\tlog.Printf(\"Ba\u015far\u0131l\u0131 sorgu hatas\u0131: %v\", err)\n\t} else {\n\t\tfmt.Printf(\"Kullan\u0131c\u0131 ad\u0131: %s\\n\", userName)\n\t}\n\n\t\/\/ 2. senaryo: Zaman a\u015f\u0131m\u0131na u\u011frayan sorgu (taklit)\n\t\/\/ Normalde veritaban\u0131 sorgusu h\u0131zl\u0131d\u0131r, ancak uzun s\u00fcren bir sorguyu taklit edelim\n\t\/\/ Bu \u00f6rnekte, SQLite bellek i\u00e7i oldu\u011fundan, ger\u00e7ekten uzun s\u00fcrmeyecektir.\n\t\/\/ Ancak, ger\u00e7ek bir a\u011f tabanl\u0131 DB'de bu, a\u011f gecikmesi veya yava\u015f sorgu nedeniyle olu\u015fabilir.\n\tctx2, cancel2 := context.WithTimeout(context.Background(), 10*time.Millisecond) \/\/ \u00c7ok k\u0131sa zaman a\u015f\u0131m\u0131\n\tdefer cancel2()\n\n\t\/\/ Uzun s\u00fcren bir i\u015flem taklidi\n\tgo func() {\n\t\t\/\/ Ger\u00e7ek bir DB sorgusunun uzun s\u00fcrmesi durumunda ctx2.Done() dinlenir\n\t\t\/\/ Burada, QueryRowContext \u00e7a\u011fr\u0131s\u0131, ctx2'nin zaman a\u015f\u0131m\u0131na u\u011framas\u0131n\u0131 bekleyecektir.\n\t\t_, err := getUserByID(ctx2, db, 1) \/\/ Bu sorgunun ba\u015far\u0131s\u0131z olmas\u0131 bekleniyor\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Zaman a\u015f\u0131m\u0131 sorgu hatas\u0131 (beklendi\u011fi gibi): %v\\n\", err)\n\t\t} else {\n\t\t\tfmt.Println(\"Zaman a\u015f\u0131m\u0131 beklenirken sorgu tamamland\u0131! (Beklenmeyen durum)\")\n\t\t}\n\t}()\n\n\ttime.Sleep(50 * time.Millisecond) \/\/ Zaman a\u015f\u0131m\u0131n\u0131n tetiklenmesi i\u00e7in biraz bekle\n\n\t\/\/ 3. senaryo: Manuel iptal edilen sorgu\n\tctx3, cancel3 := context.WithCancel(context.Background())\n\tgo func() {\n\t\t_, err := getUserByID(ctx3, db, 1)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Manuel iptal sorgu hatas\u0131 (beklendi\u011fi gibi): %v\\n\", err)\n\t\t} else {\n\t\t\tfmt.Println(\"Manuel iptal beklenirken sorgu tamamland\u0131! (Beklenmeyen durum)\")\n\t\t}\n\t}()\n\n\tfmt.Println(\"Manuel olarak sorguyu 20ms sonra iptal et...\")\n\ttime.Sleep(20 * time.Millisecond)\n\tcancel3()\n\ttime.Sleep(10 * time.Millisecond) \/\/ \u0130ptalin i\u015flenmesi i\u00e7in k\u0131sa bekleme\n}\n  <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki \u00f6rnekte, <code>getUserByID<\/code> ve <code>insertUser<\/code> fonksiyonlar\u0131 bir <code>Context<\/code> parametresi kabul eder. <code>QueryRowContext<\/code> ve <code>ExecContext<\/code> gibi veritaban\u0131 metotlar\u0131, bu <code>Context<\/code>'i kullanarak ilgili veritaban\u0131 i\u015fleminin iptal edilip edilmeyece\u011fini veya zaman a\u015f\u0131m\u0131na u\u011fray\u0131p u\u011framad\u0131\u011f\u0131n\u0131 kontrol eder. \u00d6rne\u011fin, <code>ctx2<\/code>'ye \u00e7ok k\u0131sa bir zaman a\u015f\u0131m\u0131 (10 milisaniye) uyguland\u0131\u011f\u0131nda, <code>getUserByID<\/code> fonksiyonu veritaban\u0131 i\u015flemini tamamlamadan \u00f6nce <code>Context<\/code> zaman a\u015f\u0131m\u0131na u\u011frar ve bir hata d\u00f6nd\u00fcr\u00fcl\u00fcr. Bu sayede, yava\u015f veritaban\u0131 sorgular\u0131 uygulaman\u0131n geri kalan\u0131n\u0131 bloklamaz ve kaynaklar\u0131n gereksiz yere me\u015fgul edilmesini \u00f6nler.<\/p>\n<p>Bu yakla\u015f\u0131m, \u00f6zellikle mikroservis mimarilerinde veya \u00e7ok say\u0131da harici servisle etkile\u015fimde bulunan uygulamalarda hayati \u00f6neme sahiptir. Uzun s\u00fcren veritaban\u0131 kilitleri veya a\u011f gecikmeleri nedeniyle bir servisin tak\u0131l\u0131p kalmas\u0131 yerine, <code>context<\/code> sayesinde bu i\u015flemlerin kontroll\u00fc bir \u015fekilde sonland\u0131r\u0131lmas\u0131 sa\u011flan\u0131r. Bu, uygulaman\u0131z\u0131n genel yan\u0131t verme h\u0131z\u0131n\u0131 ve kararl\u0131l\u0131\u011f\u0131n\u0131 art\u0131r\u0131r. Ayr\u0131ca, <code>context.WithValue<\/code> kullanarak bir veritaban\u0131 i\u015flemine transaction ID'si veya kullan\u0131c\u0131 oturum bilgileri gibi meta verileri eklemek, loglama ve hata ay\u0131klama s\u00fcre\u00e7lerini de kolayla\u015ft\u0131r\u0131r.<\/p>\n<h2>En \u0130yi Uygulamalar ve \u0130leri D\u00fczey Konular: context'i Daha Verimli Kullanmak<\/h2>\n<p><code>context<\/code> paketini etkili bir \u015fekilde kullanmak, sadece temel fonksiyonlar\u0131n\u0131 bilmekle kalmaz, ayn\u0131 zamanda Go programlamadaki baz\u0131 en iyi uygulamalar\u0131 ve daha ileri d\u00fczey konular\u0131 da anlamay\u0131 gerektirir. Bu b\u00f6l\u00fcm, <code>context<\/code>'i daha verimli kullanman\u0131za yard\u0131mc\u0131 olacak ipu\u00e7lar\u0131n\u0131, yayg\u0131n hatalardan ka\u00e7\u0131nma yollar\u0131n\u0131 ve performans \u00fczerindeki etkilerini ele alacakt\u0131r. Do\u011fru kullan\u0131m, uygulaman\u0131z\u0131n daha sa\u011flam, bak\u0131m\u0131 kolay ve performansl\u0131 olmas\u0131n\u0131 sa\u011flar.<\/p>\n<h3><code>context.WithValue<\/code> Kullan\u0131m\u0131: Veri Aktar\u0131m\u0131nda Nelere Dikkat Etmeli?<\/h3>\n<p><code>context.WithValue<\/code> fonksiyonu, bir <code>Context<\/code>'e istek kapsaml\u0131, de\u011fi\u015fmez verileri eklemenizi sa\u011flar. Bu, genellikle bir HTTP iste\u011fi boyunca kullan\u0131c\u0131 kimli\u011fi, izleme kimli\u011fi (tracing ID), yetkilendirme bilgileri veya di\u011fer meta verileri goroutine'ler aras\u0131nda g\u00fcvenli bir \u015fekilde aktarmak i\u00e7in kullan\u0131l\u0131r. Ancak, bu fonksiyonu kullan\u0131rken dikkat etmeniz gereken \u00f6nemli noktalar vard\u0131r:<\/p>\n<ul>\n<li>\n      <strong>Sadece \u0130ste\u011fe Ba\u011fl\u0131 (Request-Scoped) Veriler \u0130\u00e7in:<\/strong> <code>WithValue<\/code>, fonksiyon parametreleri yerine ge\u00e7memelidir. Global veya genel olarak eri\u015filebilir veriler i\u00e7in kullanmay\u0131n. Sadece belirli bir iste\u011fin ya\u015fam d\u00f6ng\u00fcs\u00fc boyunca ge\u00e7erli olan, opsiyonel ve kritik olmayan veriler i\u00e7in uygundur.\n    <\/li>\n<li>\n      <strong>Anahtar T\u00fcr\u00fc:<\/strong> \u00c7ak\u0131\u015fmalar\u0131 \u00f6nlemek i\u00e7in anahtar olarak d\u0131\u015fa aktar\u0131lmam\u0131\u015f (unexported) bir t\u00fcr kullan\u0131n. Genellikle, bo\u015f bir yap\u0131 t\u00fcr\u00fc bu ama\u00e7la kullan\u0131l\u0131r. Bu, farkl\u0131 paketlerin ayn\u0131 anahtar de\u011ferini yanl\u0131\u015fl\u0131kla kullanmas\u0131n\u0131 engeller.<\/p>\n<pre><code>\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n)\n\n\/\/ traceIDKey d\u0131\u015fa aktar\u0131lmam\u0131\u015f bir t\u00fcrd\u00fcr, \u00e7ak\u0131\u015fmalar\u0131 \u00f6nler.\ntype traceIDKey struct{}\n\nfunc processRequest(ctx context.Context) {\n\t\/\/ context'ten traceID'yi al\n\tif traceID, ok := ctx.Value(traceIDKey{}).(string); ok {\n\t\tfmt.Printf(\"\u0130stek i\u015fleniyor, Trace ID: %s\\n\", traceID)\n\t} else {\n\t\tfmt.Println(\"\u0130stek i\u015fleniyor, Trace ID yok.\")\n\t}\n\n\t\/\/ Bu context'i alt fonksiyonlara veya goroutine'lere ilet\n\t\/\/ \u00d6rne\u011fin, bir veritaban\u0131 \u00e7a\u011fr\u0131s\u0131 veya ba\u015fka bir mikroservis \u00e7a\u011fr\u0131s\u0131\n\tgo func(c context.Context) {\n\t\tif subTraceID, ok := c.Value(traceIDKey{}).(string); ok {\n\t\t\tfmt.Printf(\"Alt goroutine'de Trace ID: %s\\n\", subTraceID)\n\t\t}\n\t}(ctx)\n}\n\nfunc main() {\n\t\/\/ Ana context'i olu\u015ftur\n\tctx := context.Background()\n\n\t\/\/ context'e trace ID ekle\n\tctxWithTrace := context.WithValue(ctx, traceIDKey{}, \"abc-123-xyz\")\n\n\t\/\/ \u0130\u015flemi ba\u015flat\n\tprocessRequest(ctxWithTrace)\n\n\t\/\/ Trace ID olmayan bir i\u015flem\n\tfmt.Println(\"\\nTrace ID'siz i\u015flem:\")\n\tprocessRequest(ctx)\n\n\t\/\/ Biraz bekleyelim ki goroutine \u00e7\u0131kt\u0131s\u0131n\u0131 g\u00f6relim\n\tfmt.Println(\"Bekleniyor...\")\n\t\/\/ E\u011fer main sonlan\u0131rsa goroutine de sonlan\u0131r.\n\t\/\/ Bu y\u00fczden genellikle channel veya sync.WaitGroup ile goroutine'in bitmesi beklenir.\n\t\/\/ Basitlik i\u00e7in burada eklemedim.\n}\n      <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n      <strong>De\u011fi\u015fmezlik:<\/strong> <code>Context<\/code>'e eklenen de\u011ferler de\u011fi\u015fmez olmal\u0131d\u0131r. Context'ten al\u0131nan bir de\u011feri de\u011fi\u015ftirmeye \u00e7al\u0131\u015fmak, e\u015fzamanl\u0131l\u0131k sorunlar\u0131na yol a\u00e7abilir.\n    <\/li>\n<li>\n      <strong>Performans Etkisi:<\/strong> <code>WithValue<\/code>, hiyerar\u015fik bir yap\u0131 olu\u015fturur ve her de\u011fer eri\u015fimi, a\u011fa\u00e7ta yukar\u0131 do\u011fru bir arama gerektirir. A\u015f\u0131r\u0131ya ka\u00e7madan ve derin i\u00e7 i\u00e7e <code>Context<\/code>'ler olu\u015fturmadan kullanmaya \u00f6zen g\u00f6sterin. Genellikle bu performans etkisi ihmal edilebilir d\u00fczeydedir, ancak \u00e7ok s\u0131k ve derin arama yap\u0131lan senaryolarda g\u00f6z \u00f6n\u00fcnde bulundurulmal\u0131d\u0131r.\n    <\/li>\n<\/ul>\n<div class=\"expert-tip\">\n    Uzman \u0130pucu: <code>context.WithValue<\/code> kullanarak b\u00fcy\u00fck veri yap\u0131lar\u0131n\u0131 veya iste\u011fe ba\u011fl\u0131 fonksiyon arg\u00fcmanlar\u0131n\u0131 iletmekten ka\u00e7\u0131n\u0131n. Bu t\u00fcr durumlar i\u00e7in do\u011frudan fonksiyon parametrelerini veya yap\u0131 alanlar\u0131n\u0131 kullanmak daha uygun ve Go'nun felsefesine daha yak\u0131nd\u0131r. <code>Context<\/code>'i temiz ve sadece temel meta veriler i\u00e7in kullanmak, kodunuzu daha okunabilir ve \u00f6ng\u00f6r\u00fclebilir hale getirir.\n  <\/div>\n<h3>context'i Do\u011fru \u015eekilde Fonksiyonlara Nas\u0131l Ge\u00e7irmeliyiz?<\/h3>\n<p>Go toplulu\u011funda <code>context.Context<\/code>'in fonksiyonlara nas\u0131l iletilmesi gerekti\u011fi konusunda yayg\u0131n kabul g\u00f6rm\u00fc\u015f bir kural vard\u0131r:<\/p>\n<ul>\n<li>\n      <strong>Her zaman ilk parametre olarak:<\/strong> Bir fonksiyonun <code>context.Context<\/code>'e ihtiyac\u0131 varsa, bu parametre her zaman fonksiyon imzas\u0131n\u0131n ilk parametresi olmal\u0131d\u0131r.<\/p>\n<pre><code>\n\/\/ Do\u011fru kullan\u0131m: ctx ilk parametre olarak\nfunc MyFunction(ctx context.Context, arg1 string, arg2 int) error {\n    \/\/ ...\n    return nil\n}\n\n\/\/ Yanl\u0131\u015f kullan\u0131m: ctx son parametre veya arada bir yerde\n\/\/ func MyFunction(arg1 string, ctx context.Context, arg2 int) error { ... }\n\/\/ func MyFunction(arg1 string, arg2 int, ctx context.Context) error { ... }\n      <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n      <strong>Fonksiyon parametresi olarak ge\u00e7irin, yap\u0131 alan\u0131 olarak de\u011fil:<\/strong> <code>Context<\/code>'i bir struct'\u0131n alan\u0131 olarak saklamaktan ka\u00e7\u0131n\u0131n. Bunun yerine, ilgili metotlara parametre olarak ge\u00e7irin. <code>Context<\/code>, belirli bir i\u015flem ak\u0131\u015f\u0131 i\u00e7in ge\u00e7erlidir ve genellikle bir nesnenin \u00f6mr\u00fc boyunca sabit kalmaz.<\/p>\n<pre><code>\n\/\/ Do\u011fru kullan\u0131m: Context metotlara parametre olarak ge\u00e7er\ntype Service struct {\n    db *sql.DB\n}\n\nfunc (s *Service) GetUser(ctx context.Context, userID string) (*User, error) {\n    \/\/ db.QueryRowContext(ctx, ...)\n    return nil, nil\n}\n\n\/\/ Yanl\u0131\u015f kullan\u0131m: Context'i struct i\u00e7inde saklamak\n\/\/ type Service struct {\n\/\/     ctx context.Context \/\/ K\u00f6t\u00fc pratik\n\/\/     db  *sql.DB\n\/\/ }\n      <\/pre>\n<p><\/code>\n    <\/li>\n<li>\n      <strong>Bo\u015f Context Kullan\u0131m\u0131ndan Ka\u00e7\u0131n\u0131n:<\/strong> Fonksiyonlar genellikle bir <code>Context<\/code> parametresi beklerken, do\u011frudan <code>nil<\/code> veya <code>context.Background()<\/code>'\u0131 varsay\u0131lan olarak kullanmak yerine, \u00e7a\u011fr\u0131 yapan\u0131n uygun bir <code>Context<\/code> sa\u011flamas\u0131n\u0131 bekleyin. E\u011fer ger\u00e7ekten bir <code>Context<\/code>'e ihtiyac\u0131n\u0131z yoksa, fonksiyon imzas\u0131nda bu parametreyi bulundurmay\u0131n.\n    <\/li>\n<\/ul>\n<p>Bu kurallar, Go kodunuzun tutarl\u0131l\u0131\u011f\u0131n\u0131 art\u0131r\u0131r ve di\u011fer Go geli\u015ftiricileri taraf\u0131ndan kolayca anla\u015f\u0131lmas\u0131n\u0131 sa\u011flar. <code>Context<\/code>'in amac\u0131na uygun kullan\u0131lmas\u0131, uygulaman\u0131z\u0131n daha mod\u00fcler ve test edilebilir olmas\u0131na da yard\u0131mc\u0131 olur. Ayr\u0131ca, bu yakla\u015f\u0131mlar, \u00f6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k projelerde, kod taban\u0131n\u0131n genel kalitesini ve s\u00fcrd\u00fcr\u00fclebilirli\u011fini art\u0131r\u0131r.<\/p>\n<p>\u00d6zetle, <code>context<\/code> paketi Go'nun e\u015fzamanl\u0131l\u0131k yeteneklerini y\u00f6netmek i\u00e7in temel bir ara\u00e7t\u0131r. \u0130ptal, zaman a\u015f\u0131m\u0131 ve veri aktar\u0131m\u0131 gibi kritik g\u00f6revleri standartla\u015ft\u0131r\u0131lm\u0131\u015f ve temiz bir API ile sunar. Do\u011fru kullan\u0131ld\u0131\u011f\u0131nda, Go uygulamalar\u0131n\u0131z\u0131n daha diren\u00e7li, performansl\u0131 ve bak\u0131m\u0131 kolay olmas\u0131n\u0131 sa\u011flar.<\/p>\n<h2>Sonu\u00e7<\/h2>\n<p>Go'nun <code>context<\/code> paketi, modern, e\u015fzamanl\u0131 ve da\u011f\u0131t\u0131k uygulamalar geli\u015ftirirken kar\u015f\u0131la\u015f\u0131lan zorluklar\u0131 ele almak i\u00e7in vazge\u00e7ilmez bir ara\u00e7t\u0131r. Bu makalede, <code>context<\/code>'in neden bu kadar \u00f6nemli oldu\u011funu, temel fonksiyonlar\u0131n\u0131 (<code>Background<\/code>, <code>TODO<\/code>, <code>WithCancel<\/code>, <code>WithTimeout<\/code>, <code>WithDeadline<\/code>, <code>WithValue<\/code>) ve ger\u00e7ek d\u00fcnya senaryolar\u0131nda nas\u0131l kullan\u0131ld\u0131\u011f\u0131n\u0131 detayl\u0131ca inceledik. Gelen HTTP isteklerinin y\u00f6netilmesinden veritaban\u0131 sorgular\u0131na zaman a\u015f\u0131m\u0131 uygulanmas\u0131na kadar geni\u015f bir yelpazede, <code>context<\/code>'in i\u015flemlerin ya\u015fam d\u00f6ng\u00fcs\u00fcn\u00fc kontrol etme, kaynak s\u0131z\u0131nt\u0131lar\u0131n\u0131 \u00f6nleme ve istek kapsaml\u0131 verileri g\u00fcvenli bir \u015fekilde aktarma yetene\u011fini g\u00f6rd\u00fck. Ayr\u0131ca, paketin do\u011fru ve verimli kullan\u0131m\u0131 i\u00e7in en iyi uygulamalar ve ileri d\u00fczey ipu\u00e7lar\u0131 \u00fczerinde durarak, Go geli\u015ftiricilerinin daha sa\u011flam ve bak\u0131m\u0131 kolay kod yazmalar\u0131na yard\u0131mc\u0131 olmay\u0131 hedefledik.<\/p>\n<p>Unutmay\u0131n, <code>context<\/code> bir \"silver bullet\" de\u011fildir ve her zaman do\u011fru \u00e7\u00f6z\u00fcm olmayabilir, ancak Go ekosistemindeki yayg\u0131n kullan\u0131m\u0131 ve sa\u011flad\u0131\u011f\u0131 faydalar g\u00f6z \u00f6n\u00fcne al\u0131nd\u0131\u011f\u0131nda, her Go geli\u015ftiricisinin ara\u00e7 setinde bulunmas\u0131 gereken temel bir beceridir. Kodunuzda <code>context<\/code>'i bilin\u00e7li ve disiplinli bir \u015fekilde kullanarak, e\u015fzamanl\u0131l\u0131k sorunlar\u0131n\u0131 daha etkin bir \u015fekilde y\u00f6netebilir ve daha g\u00fcvenilir uygulamalar in\u015fa edebilirsiniz.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<ul>\n<li>\n      <strong>S: Hangi <code>context<\/code>'i ne zaman kullanmal\u0131y\u0131m: <code>Background()<\/code> m\u0131 yoksa <code>TODO()<\/code> mu?<\/strong><\/p>\n<p><strong>C:<\/strong> <code>context.Background()<\/code>, uygulaman\u0131z\u0131n ana <code>Context<\/code>'idir ve genellikle belirli bir iste\u011fe veya ya\u015fam d\u00f6ng\u00fcs\u00fcne ba\u011fl\u0131 olmayan, en \u00fcst d\u00fczey operasyonlar i\u00e7in kullan\u0131l\u0131r. <code>context.TODO()<\/code> ise ge\u00e7ici bir yer tutucudur; hen\u00fcz hangi <code>Context<\/code>'i kullanman\u0131z gerekti\u011fine karar vermedi\u011finizde, ancak bir <code>Context<\/code> parametresi gerektiren bir fonksiyonu \u00e7a\u011f\u0131rman\u0131z gerekti\u011finde kullan\u0131l\u0131r. M\u00fcmk\u00fcn oldu\u011funca <code>Background()<\/code> veya t\u00fcretilmi\u015f bir <code>Context<\/code> kullan\u0131n ve <code>TODO()<\/code>'yu sadece k\u0131sa s\u00fcreli \"yap\u0131lacaklar\" i\u00e7in ay\u0131r\u0131n.<\/p>\n<\/li>\n<li>\n      <strong>S: <code>context.CancelFunc<\/code>'\u0131 \u00e7a\u011f\u0131rmazsam ne olur?<\/strong><\/p>\n<p><strong>C:<\/strong> <code>context.CancelFunc<\/code>'\u0131 \u00e7a\u011f\u0131rmamak, ili\u015fkili <code>Context<\/code> ve onun alt\u0131nda t\u00fcretilmi\u015f t\u00fcm <code>Context<\/code>'lerle birlikte, <code>Context<\/code> hiyerar\u015fisinde kaynak s\u0131z\u0131nt\u0131lar\u0131na yol a\u00e7abilir. Bu, <code>Context<\/code>'in iptal sinyalini bekleyen goroutine'lerin s\u00fcresiz olarak ask\u0131da kalmas\u0131na ve bellekte birikmesine neden olabilir. Bu nedenle, <code>WithCancel<\/code>, <code>WithTimeout<\/code> veya <code>WithDeadline<\/code> ile bir <code>Context<\/code> olu\u015fturdu\u011funuzda, d\u00f6nd\u00fcr\u00fclen <code>CancelFunc<\/code>'\u0131 genellikle bir <code>defer<\/code> ifadesiyle \u00e7a\u011f\u0131rman\u0131z kritik \u00f6neme sahiptir.<\/p>\n<\/li>\n<li>\n      <strong>S: <code>context.WithValue<\/code> ile \u00e7ok fazla veri aktarmak performans sorunu yarat\u0131r m\u0131?<\/strong><\/p>\n<p><strong>C:<\/strong> <code>context.WithValue<\/code>, istek kapsaml\u0131, k\u00fc\u00e7\u00fck ve de\u011fi\u015fmez meta verileri aktarmak i\u00e7in tasarlanm\u0131\u015ft\u0131r. Her <code>Value()<\/code> \u00e7a\u011fr\u0131s\u0131, de\u011ferin bulunana kadar <code>Context<\/code> a\u011fac\u0131nda yukar\u0131 do\u011fru bir arama yapar. Bu i\u015flem genellikle \u00e7ok hafiftir. Ancak, \u00e7ok say\u0131da de\u011feri veya b\u00fcy\u00fck veri yap\u0131lar\u0131n\u0131 <code>Context<\/code> arac\u0131l\u0131\u011f\u0131yla aktarmak, bu arama maliyetini art\u0131rabilir ve kodun okunabilirli\u011fini azaltabilir. Genel kural, \u00f6nemli veya iste\u011fe ba\u011fl\u0131 arg\u00fcmanlar i\u00e7in do\u011frudan fonksiyon parametrelerini kullanmakt\u0131r. <code>Context<\/code>'i sadece tracing ID'leri, kimlik do\u011frulama bilgileri gibi k\u00fc\u00e7\u00fck meta veriler i\u00e7in kullan\u0131n.<\/p>\n<\/li>\n<li>\n      <strong>S: <code>Context<\/code>'i neden bir struct alan\u0131 olarak saklamamal\u0131y\u0131m?<\/strong><\/p>\n<p><strong>C:<\/strong> Bir <code>Context<\/code>, belirli bir i\u015flem ak\u0131\u015f\u0131n\u0131n veya iste\u011fin ya\u015fam d\u00f6ng\u00fcs\u00fcyle ili\u015fkilidir ve zamanla iptal edilebilir veya zaman a\u015f\u0131m\u0131na u\u011frayabilir. Bir <code>Context<\/code>'i bir struct alan\u0131 olarak saklamak, o struct'\u0131 kullanan farkl\u0131 operasyonlar\u0131n ayn\u0131, potansiyel olarak iptal edilmi\u015f veya eski <code>Context<\/code>'i kullanmas\u0131na neden olabilir. Bu da beklenmeyen davran\u0131\u015flara veya hatalara yol a\u00e7abilir. En iyi pratik, <code>Context<\/code>'i her zaman ilgili metotlara veya fonksiyonlara parametre olarak ge\u00e7irmektir, b\u00f6ylece her i\u015flem kendi uygun <code>Context<\/code>'ine sahip olur.<\/p>\n<\/li>\n<\/ul>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Modern Go uygulamalar\u0131 geli\u015ftirirken, e\u015fzamanl\u0131l\u0131k ve hata y\u00f6netimi ka\u00e7\u0131n\u0131lmaz zorluklard\u0131r. Peki, uzun s\u00fcren bir i\u015flem devam ederken kullan\u0131c\u0131&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-34246","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Go&#039;nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu<\/title>\n<meta name=\"description\" content=\"Modern Go uygulamalar\u0131 geli\u015ftirirken, e\u015fzamanl\u0131l\u0131k ve hata y\u00f6netimi ka\u00e7\u0131n\u0131lmaz zorluklard\u0131r. Peki, uzun s\u00fcren bir i\u015flem devam ederken kullan\u0131c\u0131 iste\u011fini iptal etmek, veritaban\u0131 sorgusuna bir zaman a\u015f\u0131m\u0131 uygulamak veya mikroservisler aras\u0131nda i\u015flem kimli\u011fi ta\u015f\u0131mak gibi durumlar\u0131 nas\u0131l ele al\u0131rs\u0131n\u0131z? \u0130\u015fte tam bu noktada, Go&#039;nun context paketi devreye girerek bu karma\u015f\u0131k senaryolar\u0131 zarif ve etkili bir \u015fekilde y\u00f6netmenizi sa\u011flar.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Go&#039;nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu\" \/>\n<meta property=\"og:description\" content=\"Modern Go uygulamalar\u0131 geli\u015ftirirken, e\u015fzamanl\u0131l\u0131k ve hata y\u00f6netimi ka\u00e7\u0131n\u0131lmaz zorluklard\u0131r. Peki, uzun s\u00fcren bir i\u015flem devam ederken kullan\u0131c\u0131 iste\u011fini iptal etmek, veritaban\u0131 sorgusuna bir zaman a\u015f\u0131m\u0131 uygulamak veya mikroservisler aras\u0131nda i\u015flem kimli\u011fi ta\u015f\u0131mak gibi durumlar\u0131 nas\u0131l ele al\u0131rs\u0131n\u0131z? \u0130\u015fte tam bu noktada, Go&#039;nun context paketi devreye girerek bu karma\u015f\u0131k senaryolar\u0131 zarif ve etkili bir \u015fekilde y\u00f6netmenizi sa\u011flar.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-13T20:31:22+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Go&#8217;nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu\",\"datePublished\":\"2025-11-13T20:31:22+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/\"},\"wordCount\":4078,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/\",\"name\":\"Go'nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-13T20:31:22+00:00\",\"description\":\"Modern Go uygulamalar\u0131 geli\u015ftirirken, e\u015fzamanl\u0131l\u0131k ve hata y\u00f6netimi ka\u00e7\u0131n\u0131lmaz zorluklard\u0131r. Peki, uzun s\u00fcren bir i\u015flem devam ederken kullan\u0131c\u0131 iste\u011fini iptal etmek, veritaban\u0131 sorgusuna bir zaman a\u015f\u0131m\u0131 uygulamak veya mikroservisler aras\u0131nda i\u015flem kimli\u011fi ta\u015f\u0131mak gibi durumlar\u0131 nas\u0131l ele al\u0131rs\u0131n\u0131z? \u0130\u015fte tam bu noktada, Go'nun context paketi devreye girerek bu karma\u015f\u0131k senaryolar\u0131 zarif ve etkili bir \u015fekilde y\u00f6netmenizi sa\u011flar.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Go&#8217;nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Go'nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu","description":"Modern Go uygulamalar\u0131 geli\u015ftirirken, e\u015fzamanl\u0131l\u0131k ve hata y\u00f6netimi ka\u00e7\u0131n\u0131lmaz zorluklard\u0131r. Peki, uzun s\u00fcren bir i\u015flem devam ederken kullan\u0131c\u0131 iste\u011fini iptal etmek, veritaban\u0131 sorgusuna bir zaman a\u015f\u0131m\u0131 uygulamak veya mikroservisler aras\u0131nda i\u015flem kimli\u011fi ta\u015f\u0131mak gibi durumlar\u0131 nas\u0131l ele al\u0131rs\u0131n\u0131z? \u0130\u015fte tam bu noktada, Go'nun context paketi devreye girerek bu karma\u015f\u0131k senaryolar\u0131 zarif ve etkili bir \u015fekilde y\u00f6netmenizi sa\u011flar.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/","og_locale":"tr_TR","og_type":"article","og_title":"Go'nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu","og_description":"Modern Go uygulamalar\u0131 geli\u015ftirirken, e\u015fzamanl\u0131l\u0131k ve hata y\u00f6netimi ka\u00e7\u0131n\u0131lmaz zorluklard\u0131r. Peki, uzun s\u00fcren bir i\u015flem devam ederken kullan\u0131c\u0131 iste\u011fini iptal etmek, veritaban\u0131 sorgusuna bir zaman a\u015f\u0131m\u0131 uygulamak veya mikroservisler aras\u0131nda i\u015flem kimli\u011fi ta\u015f\u0131mak gibi durumlar\u0131 nas\u0131l ele al\u0131rs\u0131n\u0131z? \u0130\u015fte tam bu noktada, Go'nun context paketi devreye girerek bu karma\u015f\u0131k senaryolar\u0131 zarif ve etkili bir \u015fekilde y\u00f6netmenizi sa\u011flar.","og_url":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-13T20:31:22+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"3 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Go&#8217;nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu","datePublished":"2025-11-13T20:31:22+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/"},"wordCount":4078,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/","url":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/","name":"Go'nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-13T20:31:22+00:00","description":"Modern Go uygulamalar\u0131 geli\u015ftirirken, e\u015fzamanl\u0131l\u0131k ve hata y\u00f6netimi ka\u00e7\u0131n\u0131lmaz zorluklard\u0131r. Peki, uzun s\u00fcren bir i\u015flem devam ederken kullan\u0131c\u0131 iste\u011fini iptal etmek, veritaban\u0131 sorgusuna bir zaman a\u015f\u0131m\u0131 uygulamak veya mikroservisler aras\u0131nda i\u015flem kimli\u011fi ta\u015f\u0131mak gibi durumlar\u0131 nas\u0131l ele al\u0131rs\u0131n\u0131z? \u0130\u015fte tam bu noktada, Go'nun context paketi devreye girerek bu karma\u015f\u0131k senaryolar\u0131 zarif ve etkili bir \u015fekilde y\u00f6netmenizi sa\u011flar.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/gonun-context-paketi-dogru-kullanim-kilavuzu\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Go&#8217;nun context Paketi: Do\u011fru Kullan\u0131m K\u0131lavuzu"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34246","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=34246"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/34246\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=34246"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=34246"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=34246"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}