Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

Rails 5 में सामान्य कॉलबैक नुकसान और उनके समाधान

ActiveRecord कॉलबैक आपके मॉडल के जीवन के विभिन्न चरणों के दौरान कोड चलाने का एक आसान तरीका है।

उदाहरण के लिए, मान लें कि आपके पास एक Q&A साइट है, और आप सभी प्रश्नों के माध्यम से खोज करने में सक्षम होना चाहते हैं। हर बार जब आप किसी प्रश्न में बदलाव करते हैं, तो आप इसे ElasticSearch जैसी किसी चीज़ में इंडेक्स करना चाहेंगे। इंडेक्सिंग में समय लगता है और यह तत्काल नहीं है, इसलिए आप इसे Sidekiq के साथ बैकग्राउंड में करेंगे।

यह after_save कॉलबैक का उपयोग करने का सही समय लगता है! तो अपने मॉडल में, आप कुछ ऐसा लिखेंगे:

app/models/question.rb
class Question < ActiveRecord::Base after_save :index_for_search # ... private def index_for_search QuestionIndexerJob.perform_later(self) end end 

app/jobs/question_indexer_job.rb
class QuestionIndexerJob < ActiveJob::Base queue_as :default def perform(question) # ... index the question ... end end 

यह बहुत अच्छा काम करता है! या, कम से कम, ऐसा लगता है। जब तक आप बहुत अधिक जॉब कतार में नहीं लगाते और ये त्रुटियां दिखाई नहीं देतीं:

2015-03-10T05:29:02.881Z 52530 TID-oupf889w4 WARN: Error while trying to deserialize arguments: Couldn't find Question with 'id'=3 

ज़रूर, Sidekiq जॉब को रीट्राई करेगा और यह शायद अगली बार काम करेगा। लेकिन यह अभी भी थोड़ा अजीब है। Sidekiq उस प्रश्न को क्यों नहीं ढूंढ सकता जिसे आपने अभी सहेजा?

प्रोसेस के बीच एक रेस कंडीशन

Rails after_save कॉलबैक को रिकॉर्ड सहेजने के तुरंत बाद कॉल करता है। लेकिन उस रिकॉर्ड को अन्य डेटाबेस कनेक्शन द्वारा नहीं देखा जा सकता, जैसे कि Sidekiq उपयोग कर रहा है, जब तक कि डेटाबेस ट्रांजैक्शन कमिट नहीं हो जाता, जो थोड़ी देर बाद होता है। इसका मतलब है कि एक मौका है कि Sidekiq आपके प्रश्न को सहेजने के बाद ढूंढने की कोशिश करेगा, लेकिन इससे पहले कि आप इसे कमिट करें। यह आपके रिकॉर्ड को नहीं ढूंढ सकता, और यह फट जाता है।

यह समस्या इतनी आम है कि Sidekiq के पास इसके बारे में एक FAQ एंट्री है। और एक आसान फिक्स है।

after_save के बजाय:

app/models/question.rb
class Question < ActiveRecord::Base after_save :index_for_search # ... end 

after_commit का उपयोग करें:

app/models/question.rb
class Question < ActiveRecord::Base after_commit :index_for_search # ... end 

और आपका जॉब तब तक कतार में नहीं लगेगा जब तक Sidekiq आपका मॉडल नहीं देख सकता।

तो, जब आप एक बैकग्राउंड जॉब कतार में लगाते हैं या किसी अन्य प्रोसेस को आपके द्वारा किए गए परिवर्तन के बारे में बताते हैं, तो after_commit का उपयोग करें। यदि आप नहीं करते हैं, तो वे उस रिकॉर्ड को ढूंढने में सक्षम नहीं हो सकते जिसे आपने अभी छुआ था।

लेकिन एक और समस्या है…

ठीक है, आपने अपने कई after_save हुक को after_commit का उपयोग करने के लिए बदल दिया। सब कुछ काम करने लगता है। इसे सब चेक इन करने और घर जाने का समय, है ना?

पहले, आप अपने टेस्ट चलाना चाहेंगे:

test/models/question_test.rb
require 'test_helper' class QuestionTest < ActiveSupport::TestCase test "A saved question is queued for indexing" do assert_enqueued_with(job: QuestionIndexerJob) do Question.create(title: "Is it legal to kill a zombie?") end end end 

 1) Failure: QuestionTest#test_A_saved_question_is_queued_for_indexing [/Users/jweiss/Source/testapps/after_commit/test/models/question_test.rb:7]: No enqueued job found with {:job=>QuestionIndexerJob} 

उफ़! क्या टेस्ट को जॉब कतार में नहीं लगाना चाहिए था? वहां क्या हुआ?

डिफ़ॉल्ट रूप से, Rails प्रत्येक टेस्ट केस को अपने स्वयं के डेटाबेस ट्रांजैक्शन में लपेटता है। यह वास्तव में चीजों को गति दे सकता है। आपके द्वारा टेस्ट के दौरान किए गए सभी परिवर्तनों को पूर्ववत करने के लिए बस एक डेटाबेस कमांड लगती है।

लेकिन इसका यह भी अर्थ है कि आपका after_commit कॉलबैक नहीं चलेगा। क्योंकि after_commit कॉलबैक केवल तभी चलते हैं जब बाहरतम ट्रांजैक्शन कमिट हो चुका होता है।

जब आप टेस्ट केस के अंदर save कॉल करते हैं, तो यह अभी भी एक ट्रांजैक्शन कमिट करता है (अधिक या कम), लेकिन वह अब दूसरा-सबसे-बाहरतम ट्रांजैक्शन है। तो आपके after_commit कॉलबैक तब नहीं चलेंगे जब आप उनसे उम्मीद करते हैं। और आप उनमें जो होता है उसे टेस्ट नहीं कर सकते।

इस समस्या का भी एक आसान फिक्स है। अपने Gemfile में test_after_commit जेम शामिल करें:

Gemfile
group :test do gem "test_after_commit" end 

और आपके after_commit हुक आपके दूसरे-से-अंतिम ट्रांजैक्शन कमिट होने के बाद चलेंगे। जो आप उम्मीद कर रहे थे वही है।

आप सोच रहे होंगे, "यह अजीब है। मुझे Rails के साथ आने वाले कॉलबैक को टेस्ट करने के लिए एक पूरी अलग जेम का उपयोग क्यों करना पड़ता है? क्या यह स्वचालित रूप से नहीं होना चाहिए?"

आप सही हैं। यह अजीब है। लेकिन यह लंबे समय तक अजीब नहीं रहेगा।

एक बार Rails 5 शिप हो जाने पर, आपको test_after_commit के बारे में चिंता करने की ज़रूरत नहीं होगी। क्योंकि इस समस्या को लगभग एक महीने पहले Rails में ठीक कर दिया गया था।

मेरे अपने कोड में, मैं after_commit का बहुत उपयोग करता हूं। मैं शायद इसका उपयोग after_save से अधिक करता हूं! लेकिन यह अपनी समस्याओं और अजीब एज केस के बिना नहीं आया है।

संस्करण दर संस्करण, हालांकि, यह बेहतर हो रहा है। और जब आप after_commit का उपयोग सही स्थानों पर करते हैं, तो बहुत सारे अजीब, यादृच्छिक अपवाद बस अब नहीं होंगे।

  1. बाईबग और पाउ के साथ रेल्स में रिमोट डीबगिंग: एक चरण-दर-चरण गाइड बाईबग और पाउ के साथ रेल्स में रिमोट डीबगिंग: एक चरण-दर-चरण गाइड

    यदि आपने पहले बाईबग नहीं देखा है, तो मैं सुझाव देता हूँ कि आप इसे देखें। यह रूबी 2.x के लिए एक बेहतरीन डीबगर है। इसके लेखकों के शब्दों में: बाईबग रूबी 2 के लिए उपयोग में सरल, सुविधा संपन्न डीबगर है। यह निष्पादन नियंत्रण के लिए नए TracePoint API और कॉल स्टैक नेविगेशन के लिए नए डिबग इंस्पेक्टर API का

  1. Vue, Vuex, और रेल्स के साथ फुल-स्टैक डेवलपमेंट में महारत: एक स्केलेबल दृष्टिकोण Vue, Vuex, और रेल्स के साथ फुल-स्टैक डेवलपमेंट में महारत: एक स्केलेबल दृष्टिकोण

    स्केलेबिलिटी को ध्यान में रखते हुए फुल-स्टैक एप्लिकेशन बनाना डराने वाला हो सकता है, खासकर जब Vue और Vuex के नवीनतम संस्करण के साथ निर्माण किया जा रहा हो, जिसमें पूर्ण टाइपस्क्रिप्ट समर्थन है। यह लेख अपने पाठकों को Vuex 4.0 के साथ स्टेट मैनेजमेंट से लेकर API अनुरोधों और डेटाबेस इंटरैक्शन को संभालने त

  1. क्रोम और एज में RESULT_CODE_HUNG त्रुटि हल करें: त्वरित समाधान गाइड क्रोम और एज में RESULT_CODE_HUNG त्रुटि हल करें: त्वरित समाधान गाइड

    हालांकि कई ब्राउज़र इंटरनेट डोमेन में मजबूत पकड़ रखते हैं, गूगल क्रोम और माइक्रोसॉफ्ट एज सूची में सबसे ऊपर हैं। क्रोम दुनिया भर के लाखों उपयोगकर्ताओं के लिए पहली पसंद है, जबकि एज कई विंडोज उपयोगकर्ताओं द्वारा पसंद किया जाता है। फिर भी इन उत्कृष्ट ब्राउज़रों में भी कुछ खामियां हैं। उपयोगकर्ता इंटरनेट