अनुच्छेद 4 : ग्रैडल कॉन्फ़िगरेशन कैश का जाल
Publié le 26 September 2025
परिचय
हमारे प्लगइन बनाने की यात्रा में`site-baker`, हमने एक कड़े TDD दृष्टिकोण का पालन किया। हर सुविधा का परीक्षण किया गया, सत्यापित किया गया, और हम विश्वास के साथ आगे बढ़ रहे थे। और फिर, एक दिन, अप्रत्याशित घटना हुई। बिल्ड्स अनियमित रूप से व्यवहार करने लगे। प्लगइन के लॉजिक या कॉन्फ़िगरेशन फ़ाइलों में किए गए संशोधनों को नजरअंदाज किया जा रहा प्रतीत होता था, और हमारे कार्यात्मक परीक्षण, जो पहले विश्वसनीय थे, स्पष्ट कारण बिना विफल हो रहे थे।
इस तरह की समस्या अविश्वसनीय रूप से निराशाजनक हो सकती है। यह उपकरण की विश्वसनीयता और हमारे कोड की वैधता पर सवाल उठाता है। गहन डिबगिंग सत्र के बाद, दोषी पहचान लिया गया है: वहGradle की कॉन्फ़िगरेशन कैश.
लक्षण : भूतिया बिल्ड्स
समस्या कई तरीकों से प्रकट हो रही थी :
-
मैं एक कार्य में एक अक्षर श्रृंखला संशोधित कर रहा था`println`, लेकिन पुरानी स्ट्रिंग चलने के दौरान प्रदर्शित होती रही।
-
मैं अपनी फाइल में एक मान बदल रहा था`managed-jbake-context.yml`, लेकिन प्लगिन ऐसा व्यवहार कर रहा था जैसे फ़ाइल में कोई संशोधन नहीं किया गया था।
-
कार्यात्मक परीक्षण, जो तत्काल परीक्षण परियोजनाएँ बनाते हैं, विफल हो रहे थे क्योंकि प्लगइन प्रतीत होता था कि ताज़ा बनाई गई कॉन्फ़िगरेशन फ़ाइलों का पता नहीं लगा पा रहा है।
सब कुछ ऐसा लग रहा था जैसे Gradle हमारे बिल्ड की एक "फ़ेंटम संस्करण" को चला रहा हो, हमारे सबसे हालिया बदलावों को अनदेखा करते हुए।
जांच: कॉन्फ़िगरेशन कैश क्या है?
कन्फ़िगरेशन कैश Gradle की एक आधुनिक और बहुत शक्तिशाली विशेषता है, जो नए संस्करणों में डिफ़ॉल्ट रूप से सक्रिय है। इसका उद्देश्य बिल्ड को तेज़ करना है।
-
पहली बार चलाने पर, Gradle चरण को निष्पादित करता हैConfiguration (lecture des
build.gradle.kts, कार्यों की रचना, निर्भरताओं का समाधान) और एक कार्य ग्राफ़ बनाता है. -
इस चरण के अंत में, Gradleइस टास्क ग्राफ को सिरीयलाइज़ करेंऔर वह इसे कैश में रखता/रखती है।
-
अनुसरण करने वाले निष्पादनों में, यदि कुछ भी नहीं बदलता (बिल्ड स्क्रिप्ट्स,
gradle.properties, etc.), Gradleयह पूरी तरह से कॉन्फ़िगरेशन चरण को छोड़ देता हैऔर कैश किए गए कार्य ग्राफ़ को पुनः उपयोग करता है।
बड़े प्रोजेक्ट्स पर समय की बचत अद्भुत है। हालाँकि, इस प्रदर्शन की एक कीमत है: यह प्लगइन्स के लिखे जाने के तरीके पर सख्त नियम लागू करती है।
समस्या का कारण: एक अनुपालन न करने वाला प्लगइन
हमारा प्लगइन`site-baker`वह अनजाने में कॉन्फ़िगरेशन कैश के कई नियमों का उल्लंघन कर रहा था। एक टास्क ग्राफ़ को सीरियलाइज़ करने योग्य बनाने के लिए, टास्क में कॉम्प्लेक्स ऑब्जेक्ट्स जैसे ऑब्जेक्ट के संदर्भ नहीं होने चाहिए।`Project`या फ़ाइलों को निष्पादन चरण के दौरान मनमाने ढंग से पढ़ें।
हमारी मुख्य त्रुटि यह थी कि हमने YAML फ़ाइल की सामग्री को कार्य के निष्पादन तर्क के भीतर सीधे पढ़ा, अपने एक्सटेंशन में संग्रहीत पथ संदर्भ का उपयोग करके। यह दृष्टिकोण कैश के साथ असंगत है क्योंकि Gradle नहीं जान सकता कि फ़ाइल की सामग्री बदल गई है यदि इस पढ़ाई को मॉडल नहीं बनाया गया है एक के रूप में.कार्य प्रविष्टि(Task Input).
अस्थायी समाधान : कैश को निष्क्रिय करें
हमें अनब्लॉक करने और पूर्वानुमेय बिल्ड व्यवहार को फिर से प्राप्त करने के लिए, सबसे तेज़ समाधान कॉन्फ़िगरेशन कैश को अक्षम करना रहा। बस फ़ाइल में निम्नलिखित लाइन जोड़ें।gradle.properties`प्लगिन का उपयोग करने वाला प्रोजेक्ट (या हमारे मामले में, परीक्षण प्रोजेक्ट)`site-baker).
# site-baker/gradle.properties
org.gradle.configuration-cache=false
तुरंत, बिल्ड्स ने अपना सामान्य व्यवहार फिर से हासिल कर लिया। प्रत्येक निष्पादन ने कॉन्फ़िगरेशन चरण को फिर से शुरू किया और हमारे परिवर्तन ध्यान में रखे गए।
हालाँकि, यह एक टर्नअराउंड समाधान है, एक स्थायी समाधान नहीं। यह प्रदर्शन को त्याग देती है और हमारे प्लगइन की मूल समस्या को हल नहीं करती।
वास्तविक समाधान: प्लगिन को संगत बनाना
एक प्लगइन आधुनिक Gradle इकोसिस्टम का एक अच्छा नागरिक बनने के लिए, इसे कॉन्फ़िगरेशन कैश के साथ संगत होना चाहिए। इसका मतलब है कि हमें अपने कार्यों की ओर डेटा प्रवाह के तरीके को पुनर्विचार करने की आवश्यकता है।
कुंजी का उपयोग करने कीप्रोवाइडर एपीआईGradle के लिए. सीधे मान पास करने के बजाय (जैसे एक`String` ou un File) हमारे कार्यों के लिए, हमें बिताना चाहिए के`Property<T>`या कुछ`Provider<T>`.
।यहाँ रिफैक्टरिंग योजना :
-
कार्य प्रविष्टियों की घोषणा करें:YAML फ़ाइल को पार्स करने वाला कार्य इसे इनपुट के रूप में घोषित करना चाहिए। इसके लिए हम एनोटेशन का उपयोग करते हैं।
@InputFile.
[source,kotlin] ---- @get:InputFile अमूर्त मान configFile: RegularFileProperty ----