مقدمہ

".ہدف شدہجمهور : Gradle ڈویلپرز جن نے پہلے سے ملاقات کی bilayerd کے "جادوئی" یا غیر متوقع سلوک۔

ہماری پلاگ بنانے کی مسابقت`site-baker`, ہم نے ایک rigorous TDD approach अपनائی۔ ہر فچر کوٹسٹ کیا گیا، تصدیق کیا گیا، اور ہم اعتماد کے ساتھ آگے بڑھتے رہے۔ پھر ایک دن، غیر متوقع واقعہ پیش آیا۔ بنائڈز الگ الگ رویے سےرفتار کرنے لگی۔ پلاگ ان کی لاجک یا کنفیگریشن فائلز میں ہونے والی تبدیلیاں نظرانداز کی جانچ لگی، اور ہمارے فانکشنل ٹیسٹس، جو قبل ازیں قابل اعتماد تھے، بغیر کسی واضح وجہ کے خراب ہونا شروع ہوگئے۔

یہ قسم کا مسئلہ بے مثال ناراضگی ہو سکتا ہے۔ یہ ٹول کی قابل اعتمادی اور ہمارے کوڈ کی صحیحیت پر سوال اٹھاتا ہے۔ شدت سے ڈیبگ سیشن کے بعد، مجرم کی شناخت کر لی گئی ہے:Gradle کی کنفیگریش کیش.

علامت: فانتوم بنڈز

مسئله مختلف طرائق میں ظاہر ہوتی تھی :

  1. میں ایک کام میں ایک سٹرنگ تبدیل کر رہا تھا`println`، لیکن پرانی سٹرنگ execution کے دوران دکھائی جاتی رہی۔

  2. mein apni file mein ek qadar tabdeel kar raha tha`managed-jbake-context.yml`, پلاگینBehavior kar raha tha jaise ki file nahi badal di gayi thi.

  3. فونکشنل ٹیسٹس، جو پرانے کے ساتھ ٹیسٹ پروجیکتس بناتے ہیں، اس وجہ سے ناکام ہوگئے کیونکہ پلاگین نئی بنائے گئے کنفیگریشن فائلز کو دکھا رہا نہیں تھا۔

سب کچھ اسی طرح ہو رہا تھا جیسے Gradle ایک version fantôme ہمारा build کا Executeครا رہا تھا، ہمرے سب سے طAZA changes کو ignoreครا رہے ہو.

تحقیق: کنفیگری کیش کیا ہے؟

کنفیگریش کیش Gradle کی نسبتاً جدید اور بہت طاقتور خاصیت ہے جو نئی ورژنوں میں ڈیفالٹ طور پر فعال ہوتی ہے۔ اس کا مقصد بِلڈز کو زیادہ سے زیادہ جلد بنانا ہے۔

اصول سادہ ہے :
  1. پہلا بار چلنے پر، Gradle مرحلہ کا تنفيذ کرتا ہےتنظیم(Mطالعہ کے`build.gradle.kts`, ٹاسکوں کی تخلیق، اعتمادات کی حل) اور ایک ٹاسک گراف بناتا ہے.

  2. اس مرحلے کے آخر میں، گریڈلیہ ٹاسک گراف سیریلائز کریںاور اسے کیش میں ڈالتا ہے

  3. آئندہ چلنوں کے دوران، اگر کچھ نہیں بدل (بیلڈ سکرپٹس،gradle.properties, etc.), Gradleپوری طرح configuration کے مرحلے کو چھوڑ دیتا ہےاور کیش کردہ ٹاسک گراف کو دوبارہ استعمال کرتا ہے

بڑے پروجیکٹس پر وقت کی بچت عجیب ہے۔ تاہم، اس کارکردگی کی ایک قیمت ہے: یہ پلاگینز کے لکھنے کے طریقے پر صارف قوانین適用 کرتا ہے۔

کونفیگریشن کییش کا حیات چکر
@startuml
start
:Première exécution;
:Phase de Configuration;
:Création du graphe de tâches;
:Mise en cache du graphe;
:Phase d'Exécution;
end

start
:Exécution suivante;
if (Cache valide ?) then (oui)
  :Restauration du graphe depuis le cache;
  note right
    La phase de configuration
    est sautée !
  end note
else (non)
  :Phase de Configuration;
  :Mise à jour du cache;
endif
:Phase d'Exécution;
stop
@enduml

مشکل کا سبب: ایک غیر متوافق پلاگین

ہمارا پلاگ‑إن`site-baker`بے خبری سے، وہ تنظیم کی کش کے بعدہ قواعد خلاف ورزے کر رہا تھا۔ ایک کاموں کا گراف سِریالائز ہونے کے لیے، کاموں کو پیچیدہ اشیاء کی références شامل نہیں کرنی چاہیے، جیسے object`Project`یا فائلوں کو تعسفی طور پر عمل کے مرحلے میں پڑھنا۔

ہماری بنیادی غلط یہ تھا کہ ہم نے YAML فائل کے مواد کو مستعمل ہونے والی ٹاسک کی لوجک کے اندر直接 پڑھا، ہمارے ایکسٹینشن میں محفوظ راستے کے حوالے سے۔ یہ اندازہ کش کے ساتھ متوافق نہیں ہے کیونکہ گرادیل بتا نہیں سکتا کہ فائل کا مواد بدل گیا ہے یا نہیں اگر یہ پڑھنا کسی طرح مودل نہیں کی جائی،مثل ایکٹاسک داخلہ(Task Input)

محلول موقت : کیش کو غیر فعال کریں

ہمیں آن لیکر سے نکلنے اور پیشگئی بیلڈ کے سلوک کو متوازن کرنے کے لیے، سب سے جلد حل کوन्फگریشن کییش کو غیر فعال کرنا تھا۔ صرف فائل میں درج ذیل لائن شامل کرنے درکار ہے۔gradle.properties`پلاگ ان استعمال کرنے والی پروجرِکٹ (یا ہمارے場合 میں، ٹیسٹ پروجرِکٹ) کا`site-baker).

# site-baker/gradle.properties
org.gradle.configuration-cache=false

فوری طور پر، بِیلڈس نےاپناعادیسلوکپانالیاب۔ ہر ایکécution configuration کیمرحلہ دوبارہشروعہوجاتی تھی اور ہمارتبدیلاتذیناخذکیجاتھی۔

لیکن یہ ایک اجتزائی حل ہے، permanent حل نہیں۔ یہ کارکردگی کو قربانی دیتی ہے اور ہماری پلاگین کے بنیادی مسئلے کا حل نہیں کرتی۔

حقیقی حل : پلاگ‑ان کو متوافق بنانا

جیکھے ایک پلاگن جدید Gradle نظام کا بھلا رہنےوالا ہو، اس کو کنفیگریشن کش کے ساتھ مطابقت رکھنا ضروری ہے۔ یہ اس بات کا مطلب ہے کہ ہم کو سोंچنا ہوگا کہ ڈیٹا کی روانگی کیسے ہمارے کاموں تک ہوتی ہے، اور اس میں تبدیلی لانی ہوگی۔

کلید استعمال کرنے کی ہےفراہم کرنے والا APISGradle سے۔ بجائے جانے والی سادہ قدر (جیسے ایک`String` ou un File) ہمیں اپنے کام پر وقت گزارنا چاہیے`Property<T>`یا کچھ`Provider<T>`.

۔یہ ہے ریفакٹرنگ کا منصوبہ :

  1. کاروں کی انٹریز کا اعلان :YAML فائل کو پارس کرنے والا ٹاسک اس فائل کو انپٹ کے طور پر advertise کرنا ضروری ہے۔ اس کے لیے ہم annotation استعمال کرتے ہیں۔@InputFile.

  2. Property` اور Provider کا استعمال کریں:کی قیمت`configFile`جائیداد سے منسلک ہوگا`configPath`ہمارے DSL ایکسٹینشن کے۔ اس طرح Gradle ڈیٹا کی اصل جگہ (provenance) کو ٹریس کرنے کے قابل ہے۔

  3. درست وقت پر مواد پڑھیں:فائل کی ریڈنگ ٹاسک کے ایکشن کے اندر ہونی چاہیے (@TaskAction)، کا استعمال کرتے ہوئے`Provider`داخلے کا۔

اس نمونے پر عمل کرتے ہوئے، Gradle یہ سمجھتا ہے کہ اگر کی مواد ہے`configFile`تبديل، کنفیگریشن کیش (configuration cache) غیر فعال ہے اور کنفیگریشن کے مرحلے کو دوبارہ چلانے کی ضرورت ہے۔ مزید برآں، اسے معلوم ہے کہ ٹاسک کا آؤٹ پٹ اس فائل کے مواد پر منحصر ہے، جو رن کیش (execution cache) کو بھی آپٹمائز کرنے کی اجازت دیتا ہے (UP-TO-DATE).

نتیجہ

ڈیبگنگ کا یہ تجربہ ایک قیمتی سبق تھا۔ کنفیگریشن کیش کے "جادوئی" رویے نے ہمیں Gradle کے لائف سائیکل اور ڈیکلیریٹو اور لیزی پروگرامنگ کے اصولوں کو بہتر طور پر سمجھنے پر مجبور کیا (lazy).

کنفیگریشن کیشے (configuration cache) کو غیر فعال کرنا تشخیص کا ایک مفید ذریعہ ہے، لیکن اصل حل مضبوط اور جدید پلگ انز ڈیزائن کرنا ہے۔ ہمارے ٹاسک کے ان پٹ اور آؤٹ پٹ کو APIs کے ذریعے درست طریقے سے ماڈل کر کے`Provider`، ہم صرف ایک بگ کو درست نہیں کر رہے، بلکہ ہم اپنے پلگ ان کی کارکردگی، بھروسہ مندی اور برقرار رکھنے کی صلاحیت (maintainability) کو بہتر بنا رہے ہیں۔

اگلے مضمون میں، ہم اس ری فیکٹرنگ (refactoring) کو عملی جامہ پہنائیں گے تاکہ ہمارے YAML پارسنگ کے ٹاسک کو کنفیگریشن کیش کے ساتھ مکمل طور پر ہم آہنگ بنایا جا سکے۔

متعلقہ مضامین