2009-04-09 11 views
6

मेरे पास काफी बड़ा रेल ऐप है, जो एक अलग सर्वर पर अपने कैश स्टोर के रूप में memcached का उपयोग करता है।गलत कैश्ड ऑब्जेक्ट लौटने वाले मेमचेचे के साथ रेल?

समस्या यह है कि मुझे यादृच्छिक रूप से उत्पादन वातावरण में त्रुटियां मिलती हैं जो प्रतीत होता है कि यह संकेत करने के लिए कि memcached गलत ऑब्जेक्ट लौट रहा है।

उदाहरण:

इस उदाहरण में, current_site एक सहायक विधि है जो Site मॉडल मॉडल कैश करने के लिए Rails.cache का उपयोग करता है पर एक विधि पहुँचता

ActionView::TemplateError in ListingsController#edit 
undefined method `settings' for #<String:0xb565f8a0> 

On line #12 of app/views/layouts/site.html.erb 

    9:   <meta name="robots" content="noodp, all" /> 
    10:   <meta name="distribution" content="Global" /> 
    11: 
    12:   <% unless current_site.settings[:google_webmaster_verification_code].blank? %> 
    13:   <meta name="verify-v1" content="<%= current_site.settings[:google_webmaster_verification_code] %>" /> 
    14:   <% end %> 
    15: 

के विपरीत है ....

ActionView::TemplateError in ApplicationController#not_found 
undefined method `settings' for #<Category:0xd5c6c34> 

On line #12 of app/views/layouts/site.html.erb 

    9:   <meta name="robots" content="noodp, all" /> 
    10:   <meta name="distribution" content="Global" /> 
    11: 
    12:   <% unless current_site.settings[:google_webmaster_verification_code].blank? %> 
    13:   <meta name="verify-v1" content="<%= current_site.settings[:google_webmaster_verification_code] %>" /> 
    14:   <% end %> 
    15: 

जब दोनों को Site मॉडल लौटाया जाना चाहिए!

कैश अजीब तरीके से व्यवहार का एक और उदाहरण:

ActionView::TemplateError in AccountsController#show 
can't convert Category into String 

On line #141 of app/views/layouts/site.html.erb 

    138:     <li<%= class="first" if i == 0 %>><%= link_to top_level_category.title, top_level_category.path %></li><% end %> 
    139:    </ul> 
    140:   <% end %> 
    141:   <% cache bottom_pages do %> 
    142:    <ul><% Page.top_level.active.show_in_navigation.find(:all, :include => :slugs).each_with_index do |top_level_page, i| %> 
    143:     <li<%= class="first" if i == 0 %>><%= link_to top_level_page.title, top_level_page.path %></li><% end %> 
    144:    </ul> 

किसी को भी इस से पहले की तरह कुछ का सामना करना पड़ा है? किसी को भी इस अप्रिय समस्या का निदान करने पर विचार है !? मैंने memcached क्लाइंट रत्नों को स्विच करने का प्रयास किया है, सोच रहा है कि यह एक अजीब बग था, लेकिन इसका कोई प्रभाव नहीं पड़ा! धन्यवाद।

+0

क्या यह उत्पादन पर्यावरण या विकास मोड में होता है? – pauliephonic

उत्तर

10

यह यात्री द्वारा मेमकैड सर्वर से अपना कनेक्शन साझा करने के कारण हुआ था। http://www.modrails.com/documentation/Users%20guide.html#_example_1_memcached_connection_sharing_harmful देखें।

फिक्स बस यात्री के रेल को conservative में बदलने के लिए था।

+0

धन्यवाद! यह पिछले कुछ दिनों से मुझे पागल कर रहा है। –

+0

मैं यह नहीं बता सकता कि यह जवाब कितना शानदार था। यह हमें पागल कर रहा था! –

1
कुछ चीजें हैं जो मदद कर सकता है

:

  • current_site लिए उपकरण/प्रवेश जोड़े को देखने के लिए वास्तव में क्या वापस आ जा रहा है।
  • आप memcache में कुंजी कैसे निर्दिष्ट कर रहे हैं? आप दो अलग-अलग वस्तुओं के लिए दो अलग-अलग स्थानों में गलती से एक ही कुंजी का उपयोग कर सकते हैं।
  • अपने memcache में वास्तव में क्या है देखने के लिए memcached-tool host:port dump > /tmp/keys का उपयोग करें।
  • आपका memcached फ़ायरवॉल के पीछे है और सार्वजनिक आईपी पर खुलासा नहीं है, है ना?
+0

1) हो गया, सत्यापित करता है कि यह वास्तव में क्या हो रहा है। 2) डबल चेक किया गया, सही नहीं 3) क्या यह, लेकिन बिल्कुल यह सुनिश्चित नहीं है कि यह कैसे सहायक है? 4) सही धन्यवाद! – Ben

+0

जब तक आप अजीब व्यवहार नहीं देखते हैं, तब तक प्रतीक्षा करें, और फिर देखें कि 'memcached-tool host: port dump' क्या बाहर निकलता है, यह देखने के लिए कि क्या यह * प्रेत' डेटा भी है ... यदि नहीं, तो समस्या कहीं बाहर स्थित है memcahce के। इसके अलावा, मुझे नहीं पता ... –

0

हाँ, मैंने ऐसा किया है। मेरे साथ, ऐसा इसलिए था क्योंकि मैं Rails.cache.fetch(key) कर रहा था और कुंजी खाली थी।

मेरे द्वारा की गई कुछ रेल कंसोल में और के साथ प्रयोग करना निम्नलिखित:

Rails.cache.read validkey # Get back the proper data 
Rails.cache.fetch('') { 'abc' } # Error in rails log: 'MemCacheError():' 
Rails.cache.read validkey # Get back nil 
Rails.cache.read validkey # May get back proper data 
1

मैं इस समस्या है भी था और कैश प्रदाता द्वारा unmarshal ऑपरेशन से पहले हर वर्ग/मॉडल के लिए require_dependency जोड़ने हल किया गया था । शायद उत्पादन वातावरण में यह आवश्यक नहीं है क्योंकि विकल्प: config.cache_class सत्य पर सेट किया गया है, लेकिन परीक्षण और विकास में यह गलत है।

वास्तव में, मेमकैच (कैश प्रदाता जो मैं उपयोग कर रहा हूं) संदर्भित कक्षा को अनारशल करने के लिए नहीं मिलता है और फिर यह त्रुटि उठाता है। http://kballcodes.com/2009/09/05/rails-memcached-a-better-solution-to-the-undefined-classmodule-problem/

सादर:

इस पोस्ट में इस समस्या का थोड़ा बेहतर समाधान है!

0

किसी और के साथ आने पर किसी टिप्पणी को जोड़ने के लिए ... kballcodes.com url अब मान्य नहीं है (हालांकि आप इसे अभी भी archive.org के माध्यम से एक्सेस कर सकते हैं)। उस ब्लॉग पोस्ट पर टिप्पणियों में, किसी ने मार्शल को वस्तु को लोड करने का प्रयास करने का एक तरीका बताया, यदि यह पहली बार 'अपरिभाषित वर्ग/मॉड्यूल' त्रुटि फेंकता है। मैंने नीचे दिया गया कोड शामिल किया है, और कोड नमूना के नीचे मूल लेखक का संदर्भ दिया है।

अपने RAILS_ROOT/config/initializers/फ़ोल्डर में एक प्रारंभकर्ता फाइल करने के लिए इस जोड़ें:

# 
# Marshal.load is a C-method built into Ruby; because it's so low-level, it 
# bypasses the full classloading chain in Ruby, in particular the #const_missing 
# hook that Rails uses to auto-load classes as they're referenced. This monkey 
# patch catches the generated exceptions, parses the message to determine the 
# offending constant name, loads the constant, and tries again. 
# 
# This solution is adapted from here: 
# http://kballcodes.com/2009/09/05/rails-memcached-a-better-solution-to-the-undefined-classmodule-problem/ 
# 
class <<Marshal 
    def load_with_rails_classloader(*args) 
    begin 
     load_without_rails_classloader(*args) 
    rescue ArgumentError, NameError => e 
     if e.message =~ %r(undefined class/module) 
     const = e.message.split(' ').last 
     const.constantize 
     retry 
     else 
     raise(e) 
     end 
    end 
    end 

    alias_method_chain :load, :rails_classloader 
end 

इस के लिए सभी क्रेडिट Matt Brown जो this code as a pastie बनाया जाता है और इसके बाद के संस्करण अब मृत लेख पर टिप्पणी की:

संबंधित मुद्दे