रेल 4 की सूक्ष्मता - कैश डिजीज



एक रत्न जिसे " cache_digests " कहा जाता है (रेल में डिफ़ॉल्ट रूप से सक्षम 4) स्वचालित रूप से व्यू (दृश्य) के आधार पर प्रत्येक टुकड़ा कैश में एक डिजिटल हस्ताक्षर जोड़ता है। इस स्थिति में, यदि पेज बदल जाता है, तो पुराने कैश को स्वचालित रूप से हटा दिया जाता है। लेकिन नुकसान के खबरदार!



रेल 4 सूक्ष्मता चक्र की सामग्री



मैंने एक छोटा अनुप्रयोग लिखा जिसमें परियोजनाओं के साथ एक सूची है, जिनमें से प्रत्येक में कार्यों की एक विशिष्ट सूची है। मान लीजिए कि इस एप्लिकेशन में प्रदर्शन समस्याएं थीं और उन्हें ठीक करने के लिए टुकड़ा कैशिंग का उपयोग करने का निर्णय लिया गया था।



निम्नलिखित कोड परियोजनाओं की एक सूची प्रदर्शित करता है:

/app/views/projects/index.html.erb
<h1>Projects</h1> <%= render @projects %> 

प्रत्येक प्रोजेक्ट के लिए एक आंशिक _प्रोजेक्ट उत्पन्न होता है। यह भी काफी सरल है और कार्यों की सूची प्रदर्शित करने से संबंधित है:

/app/views/projects/_project.html.erb
 <h2><%= link_to project.name, edit_project_path(project) %></h2> <ul><%= render project.tasks %></ul> 

बदले में, _प्रोजेक्ट एक और आंशिक: _task प्रदान करता है । तो, _project के लिए फ़्रेग्मेंट कैशिंग जोड़ें।

/app/views/projects/_project.html.erb
 <% cache project do %> <h2><%= link_to project.name, edit_project_path(project) %></h2> <ul><%= render project.tasks %></ul> <% end %> 

चूंकि उपरोक्त कोड कार्यों की एक सूची प्रदर्शित करता है, इसलिए नया कार्य दिखाई देने पर पुराने डेटा को कैशिंग करना बंद करना बुद्धिमानी होगी। इस लक्ष्य को एक स्पर्श जोड़कर प्राप्त किया जा सकता है: परियोजना के संबंध में कार्य मॉडल के लिए सही :

/app/models/task.rb
 class Task < ActiveRecord::Base attr_accessible :name, :completed_at belongs_to :project, touch: true end 

अब, जब कोई प्रोजेक्ट कार्य बदलता है, तो इसे अद्यतन के रूप में चिह्नित किया जाएगा। विकास मोड में कैशिंग की जाँच करें:

/config/development.rb
 config.action_controller.perform_caching = true 

सर्वर रीस्टार्ट और पेज रिफ्रेश होने के बाद, प्रत्येक प्रोजेक्ट को टुकड़े टुकड़े कैशिंग का उपयोग करके कैश किया जाएगा। उसी समय, यदि किसी एक कार्य को संपादित किया जाता है, तो कैश समाप्त हो जाएगा और इस तरह से नया डेटा लोड किया जाएगा।

यह सब बहुत अच्छा है, लेकिन अगर परिवर्तन स्वयं पेज के कोड में किए जाते हैं तो क्या होगा? उदाहरण के लिए, मैंने क्रमांकित सूची के रूप में कार्य प्रदर्शित करने के लिए कोड को अपडेट किया:

/app/views/projects/_project.html.erb
 <% cache project do %> <h2><%= link_to project.name, edit_project_path(project) %></h2> <ol><%= render project.tasks %></ol> <% end %> 

अब ब्राउजर में पेज को रिफ्रेश करें। कोई भी दृश्य परिवर्तन नहीं हुआ है! यह इस तथ्य के कारण हुआ कि पुराने कोड वाला पृष्ठ पहले से ही कैश में संग्रहीत किया गया था, और इसकी वैधता अवधि अभी तक समाप्त नहीं हुई है। इसलिए, पुरानी सामग्री अभी भी दिखाई देती है। इस समस्या को आमतौर पर कैश कुंजी संस्करण को अपडेट करने से दरकिनार किया जाता है:

/app/views/projects/_project.html.erb
 <% cache ['v1', project] do %> <h2><%= link_to project.name, edit_project_path(project) %></h2> <ol><%= render project.tasks %></ol> <% end %> 

चूंकि मुख्य मूल्य बदल दिया गया था, इसलिए पुराना कैश अमान्य हो गया और पृष्ठ पर एक क्रमांकित सूची वाले कार्य प्रदर्शित होते हैं। हुर्रे!



लेकिन कुछ समस्या है। आपको हमेशा याद रखना चाहिए कि हर बार जब आप पृष्ठ कोड बदलते हैं, तो आपको नए परिवर्तनों को प्रभावी करने के लिए कैश की संस्करण संख्या को भी बदलना होगा। सिद्धांत रूप में, यह मुश्किल नहीं है, लेकिन अगर नेस्टेड टुकड़ा कैशिंग का उपयोग किया जाता है, तो सब कुछ तुरंत जटिल है। मान लीजिए मैं प्रदर्शन को थोड़ा और बढ़ाने के लिए आंशिक रूप से कार्य को कैश करना चाहता हूं:

/app/views/tasks/_task.html.erb
 <% cache ['v1', task] do %> <li> <%= task.name %> <%= link_to "edit", edit_task_path(task) %> </li> <% end %> 

अब आपको आंशिक रूप से प्रोजेक्ट में कैश कुंजी को अपडेट करने की भी आवश्यकता है ताकि पूरी पुरानी कैश गायब हो जाए।

उदाहरण के लिए, यदि हम लिंक को "एडिट" से "रीनेम" में बदलकर कार्य के साथ आंशिक अद्यतन करते हैं, तो यह स्पष्ट है कि आपको इसकी कैश कुंजी को बदलने की आवश्यकता है। लेकिन पृष्ठ पर कोई भी दृश्य परिवर्तन तब तक नहीं होगा जब तक कि परियोजनाओं के साथ आंशिक रूप से महत्वपूर्ण मूल्य भी नहीं बदलता है। और उसके बाद ही हम अपने लंबे समय से प्रतीक्षित नवाचारों को देखेंगे:



कैश पचता है


हां, इस तरह के कैशिंग काम करते हैं, लेकिन आपको मानना ​​होगा कि यह भयानक है। और यहाँ हमारी मदद के लिए "cache_digests" नामक एक मणि आता है! इसकी कार्यक्षमता को रेल 4 में शामिल किया गया है, लेकिन इसे एक अलग मणि के साथ भी आवंटित किया गया था ताकि डेवलपर्स इसे आज रेल 3 के साथ परियोजनाओं में उपयोग कर सकें।

इस रत्न में विचारों पर आधारित खंड कैश में डिजिटल हस्ताक्षर शामिल हैं। इसका मतलब यह है कि पेज कोड में परिवर्तन से कैश कुंजी भी बदल जाएगी, इस प्रकार पुराने को साफ कर दिया जाएगा।

आइए उसके काम को आजमाएँ। ऐसा करने के लिए, मणिभ में निम्नलिखित पंक्ति शामिल करें:

/ जेमफाइल
 gem 'cache_digests' 

और फिर:
 $ bundle install 

अब कुंजी संस्करण को निर्दिष्ट करने की कोई आवश्यकता नहीं है, और इसलिए, एक स्पष्ट विवेक के साथ, हम _project और _task भाग से अतिरिक्त कोड निकाल सकते हैं। उसके बाद, आपको सर्वर को पुनरारंभ करने और प्रभावी होने के लिए नए कैशिंग के लिए ब्राउज़र में पृष्ठ को रीफ्रेश करने की आवश्यकता है।

यदि आप ऐसा नहीं करते हैं, और उसी समय प्रोजेक्ट दृश्य के कोड को थोड़ा बदलने और पृष्ठ को अपडेट करने का प्रयास करते हैं, तो परिवर्तन नहीं होंगे। कारण यह है कि कैश डाइजेस्ट मणि हर कोड परिवर्तन के साथ विचारों में बदलाव का विश्लेषण नहीं करता है, क्योंकि यह बेहद अनुचित है। इसके बजाय, यह प्रत्येक दृश्य के लिए अपना स्थानीय कैश संग्रहीत करता है, और प्रत्येक को एक अद्वितीय डिजिटल हस्ताक्षर प्रदान करता है।

विकास मोड में परिवर्तन देखने के लिए, आपको हमारे एप्लिकेशन सर्वर को पुनरारंभ करना होगा। ऐसी समस्याओं को उत्पादन में प्रकट नहीं होना चाहिए, क्योंकि सर्वर प्रत्येक नई तैनाती के साथ वैसे भी पुनरारंभ होता है।

अब, पृष्ठ को रीफ्रेश करने के बाद, यह देखा जाएगा कि कोड में अपडेट रत्न द्वारा किसी का ध्यान नहीं गया, और हमें अंततः एक अद्यतन पृष्ठ के साथ प्रस्तुत किया गया। वैसे, मणि काफी स्मार्ट है और निर्भरता निर्धारित कर सकता है। खैर, उदाहरण के लिए, हम अभी भी याद करते हैं कि परियोजनाओं के साथ प्रस्तुति कार्यों की सूची प्रदर्शित करने के लिए रेंडर विधि को कॉल करती है। इसलिए, यह स्पष्ट है कि यदि कार्य आंशिक रूप से अचानक बदल गया है, तो परियोजना दृश्य में पुराने कैश को हटाने की आवश्यकता है।

नुकसान


लेकिन फिर भी, आपको बहुत आराम नहीं करना चाहिए, क्योंकि ऐसे संभावित मामले हैं जिनमें निर्भरता की सही पहचान नहीं की जाएगी। एक छोटे से उदाहरण पर विचार करें।

मान लीजिए कि प्रोजेक्ट मॉडल में एक अपूर्ण_ कार्य विधि मौजूद है। और मैंने इस पद्धति का उपयोग आंशिक में अधूरे कार्यों को प्रदर्शित करने के लिए किया (परियोजनाओं की सूची प्रदर्शित करने के लिए जिम्मेदार)। यदि आप ऐसा करते हैं, तो यह स्पष्ट हो जाएगा कि दृश्य में परिवर्तन प्रदर्शित नहीं किए गए थे, क्योंकि निर्भरता को सही ढंग से परिभाषित नहीं किया गया था। शायद इस मामले में एक अच्छा विचार है कि रेक कार्य कैश_डिजिस्ट: नेस्टेड_डिपेंडेंसी को चलाना होगा, इसलिए कृपया मणि द्वारा प्रदान किया जाए।

 $ rake cache_digests:nested_dependencies TEMPLATE=projects/index [ { "projects/project": [ "incomplete_tasks/incomplete_task" ] } ] 

जैसा कि आप देख सकते हैं, समस्या का विश्लेषण करने के लिए आवश्यक दृश्य का मार्ग उपरोक्त कोड से प्रेषित है।

रेक कार्य के आउटपुट से पता चलता है कि परियोजनाओं के साथ आंशिक रूप से एक निर्भरता पाई गई थी (जो अच्छी है), लेकिन इसे गलत तरीके से परिभाषित किया गया था: अपूर्ण_टैक कार्य के स्थान पर होना चाहिए। इस अप्रिय घटना को ठीक करने के लिए, मैं निम्नलिखित कोड का उपयोग करने की सलाह देता हूं (ध्यान दें कि मैं आंशिक और संग्रह का उपयोग करता हूं)

/app/views/projects/_project.html.erb
 <% cache project do %> <h2><%= link_to project.name, edit_project_path(project) %></h2> <ul><%= render partial: 'tasks/task', collection: project.incomplete_tasks %></ul> <% end %> 

एक ही रेक कार्य को फिर से चलाने से, यह स्पष्ट हो जाएगा कि निर्भरता अब ठीक से परिभाषित की गई है और कैश को सफलतापूर्वक अपडेट किया गया है!

 $ rake cache_digests:nested_dependencies TEMPLATE=projects/index [ { "projects/project": [ "tasks/task" ] } ] 

मणि के काम के बारे में अधिक विवरण इसके README में पाया जा सकता है, जिसे मैं हर किसी को दिलचस्पी बनाने की सलाह देता हूं। आपका ध्यान के लिए धन्यवाद!

सभी त्रुटियों के बारे में, अनुवाद की गलतियाँ और अन्य समान चीजों के बारे में, कृपया पीएम को सूचित करें।



आवेदन
पाठ से आवेदन का स्रोत कोड


मेरे ब्लॉग को सब्सक्राइब करें !

Source: https://habr.com/ru/post/In165355/


All Articles