کنجکاوی که ۶۰٪ از حافظه رو آزاد کرد
خلاصهٔ کاملتر
نویسنده اول یه نکتهٔ آشنا رو یادآوری میکنه: ایجنتهای کدنویسی وقتی خروجی یه دستور رو میخونن، معمولاً نویز رو فیلتر میکنن تا سیگنال بهتر دیده شه. خودش هم دیده که ایجنت داره یه هشدار Ruby رو از خروجی rspec حذف میکنه؛ هشداری دربارهٔ بازتعریف object_id توی aws-sdk-core. موضوع اصلاً توی محدودهٔ تسکش نبود، ولی به قانون پیشاهنگی پایبند موند و گفت لااقل یه بررسی سریع بکنه.
ریشهاش ناسازگاری opentelemetry-instrumentation-aws_sdk با نسخهٔ پینشدهٔ ۲ از aws-sdk بود. اپلیکیشن با use_all همهٔ instrumentationهای OTel رو فعال میکرد و بلوک نصبِ این یکی، متد loaded_service_clients رو صدا میزد که روی تکتک ثابتهای Aws عملیات const_get انجام میده. چون توی نسخهٔ ۲ همهٔ سرویسها autoload هستن، همین کار حدود ۲۰۰ سرویس رو موقع بوت بهزور لود میکرد؛ از جمله DataPipeline که یه accessor به اسم object_id میسازه و هشدار همیشگی Ruby رو در میآره.
راهحل هم پیچیده نبود: یه ماژول با prepend جلوی کلاس Instrumentation قرار میگیره و loaded_service_clients رو طوری بازنویسی میکنه که ثابتهایی که هنوز autoload هستن رو رد کنه و فقط سرویسهایی رو برداره که واقعاً لود شدن.
def loaded_service_clients
::Aws.constants.each_with_object([]) do |c, constants|
next if ::Aws.autoload?(c)
m = ::Aws.const_get(c)
next unless loaded_service?(c, m)
constants << m.const_get(:Client)
end
endنتیجهٔ بنچمارکی که خودش گرفته گویاست: فایلهای aws-sdk-core از ۲۵۹ به ۲ رسید، سرویسهای لودشده از ۲۲۰ به صفر، تعداد کلاسهای داخل VM از ۳۳٬۲۶۵ به ۱۳٬۱۳۷ (۶۰٪ کمتر)، حافظهٔ heap از ۱۶۳٫۸ به ۶۷٫۱ مگابایت (۵۹٪ کمتر) و زمان بوت گرم از ۲٫۶۹ به ۱٫۷۲ ثانیه (۳۶٪ کمتر). فیکس هم با تست واحد پوشش داده شد تا مطمئن شن لیست instrumentationها عوض نشده و هشدار هم رفته.
حرف اصلی نویسنده اینه که بهتر کردن کدبیسی که هر روز باهاش سروکار داریم هیچوقت اینقدر ارزون نبوده؛ نه لوپ لازم داره نه هیوریستیک پیچیده نه بلوکهای زمانی بزرگ، فقط یه ذره کنجکاوی. قدمهای کوچیک بردار و جا رو یهکم بهتر از چیزی که تحویل گرفتی تحویل بده؛ هم برای خودِ آیندهت، هم برای ایجنتها و هم برای تیم.
نکات کلیدی:
- فیلترشدن یه هشدار توسط ایجنت میتونه نشونهٔ یه مشکل واقعی باشه
- use_all توی OTel همهٔ instrumentationها رو فعال میکنه، با همهٔ عوارضش
- توی aws-sdk نسخهٔ ۲ همهٔ سرویسها autoload هستن و const_get روی همهشون یعنی لودشدن کل کاتالوگ
- پچ با prepend جلوی لودشدن سرویسهای استفادهنشده رو گرفت
- ۶۰٪ کلاس کمتر، ۵۹٪ حافظهٔ کمتر و ۳۶٪ بوت سریعتر
- نسخهٔ جدید aws-sdk مدل «هر قابلیت، یک gem» رو داره و اصلاً این مشکل رو نمیساخت




