نمونه ای از یک نشت گوروتین و نحوه اشکال زدایی یک

وقتی به یک کارکرد نزدیک می شوم که در حال اجرای یک قطعه کد در یک شبکه و ارتباط / لغو استفاده از کانال ها است ، معمولاً وسوسه می شوم که عمیق تر به نظر بیایم چون مکانی عالی برای معرفی یک نشت goroutine به راحتی است و این خطاها بسیار آسان هستند حتی برای توسعه دهنده های مبتدی golang فراموش نکنید. و این کاری است که من برای این قطعه کدی که در KUDO پیدا کردم انجام دادم.

نشت گوروتین چیست؟

نشت گوروتین در اصل نوعی نشت حافظه است. شما شروع به ایجاد یک دوره گردی می کنید اما این کار هرگز خاتمه نمی یابد ، و برای همیشه خاطراتی را که رزرو کرده است را اشغال می کنید. برای ساده کردن نمونه ای که من از KUDO کمی ارسال کردم ، این نمونه ای از چگونگی معرفی یک نشت گوروتین در پروژه خود است.

آنچه کد انجام می دهد این است که یک مدت زمان اجباری و یک عمل تناوبی در داخل یک گوروین وجود دارد. با هر لحظه ، سعی می کنیم برخی از منطق کسب و کار را تأیید کنیم (ادعا کنید که چیزی سالم است / برای مثال آماده است) - در این مثال ، آن تماس را فقط با خوابیدن و سپس بازگشت ، شبیه سازی می کند.

پس نشت کجاست؟ در مثال ساده در بالا ، زمان اتمام فقط 1 ثانیه است در حالی که عملیات تأیید 10 ثانیه طول می کشد. این بدان معناست که ابتدا مهلت اجرا می شود و با بازگشت از "انتظار آماده" می شود. حدود 9 ثانیه بعد ، نتیجه ما از نتیجه تأیید صحت دریافت می کند و سعی می کند که به کار خودتان انجام دهد. نوشتن در کانال غیر مسدود شده مسدود شده است و هیچ کس در آن کانال گوش نمی دهد زیرا ما قبلاً از waitReady برگشتیم - و در اینجا نشت ما وجود دارد!

چگونه می توان فهمید که شما دارای نشت گوروتین هستید؟

به طور کلی ، بسته "runtime" دوست شما در اینجا است. یک روش استفاده از runtime.NumGoroutine () در یک تست قبل و بعد از فراخوانی تابع waitReady است. اگر تعداد گوروتین ها قبل از انتظارReady و بعد از آن یکسان نیست ، یک نشت دارید.

گزینه دیگر استفاده از کتابخانه Uber - goleak است. اگر به چگونگی اجرای آن شیرجه بزنید ، به بسته اجرا نیز متکی است ، این بار تمام پشته ها (عملکرد runtime.Stack) را می خواند و در بالای آن چند روش راحتی را معرفی می کند.