2009-03-19 15 views
11

क्या रेल में प्रति-अनुरोध डेटा कैश करने का कोई तरीका है? किसी दिए गए रेल/मोंगेल अनुरोध के लिए मेरे पास एक अर्ध-महंगी ऑपरेशन का नतीजा है जिसे मैं उस अनुरोध में कई बार एक्सेस करना चाहता हूं। क्या कोई हैश है जहां मैं ऐसे डेटा को स्टोर और एक्सेस कर सकता हूं?रेल प्रति अनुरोध हैश?

इसे रेल, कैश और आई 18 एन जैसे विचारों, नियंत्रकों और libs से काफी वैश्विक और सुलभ होना आवश्यक है।

मैं कुछ बंदर-पैचिंग कर रहा हूं अगर ऐसा होता है।

  • मेमकैड काम नहीं करता है क्योंकि इसे अनुरोधों में साझा किया जाएगा, जो मैं नहीं चाहता हूं।
  • एक वैश्विक चर समान रूप से काम नहीं करता है क्योंकि अलग-अलग अनुरोध समान डेटा साझा करेंगे, जो मैं नहीं चाहता हूं।
  • इंस्टेंस वैरिएबल काम नहीं करते क्योंकि मैं विभिन्न वर्गों के अंदर से डेटा तक पहुंचना चाहता हूं।
+0

आप कहते हैं कि आप चाहते हैं यह अनुरोध (बुलेट 1) भर में साझा करने के लिए, लेकिन यह भी आप अनुरोध साझा नहीं करना चाहते हैं कि (बुलेट 2)। मुझे लगता है कि मुझे पता है कि आपका क्या मतलब है, लेकिन आपको स्पष्टीकरण देना चाहिए। –

+0

बुलेट 1 में मैं कहता हूं कि मैं _don't_ इसे अनुरोधों में साझा नहीं करना चाहता हूं। –

उत्तर

4

PerRequestCache आज़माएं। मैंने एसक्यूएल क्वेरी कैश से डिज़ाइन चुरा लिया।

इसके साथ config/environment.rb में विन्यस्त अप:

config.middleware.use PerRequestCache 

तो साथ उपयोग:

PerRequestCache.fetch(:foo_cache){ some_expensive_foo } 
+0

जैसा कि आपकी जिंद बताती है, यह थ्रेड-सुरक्षित नहीं है। मैं बस एसक्यूएल क्वेरी कैश में सामान को छीनने लगा। यह एक हैक है, लेकिन यह काम करता है। –

1

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

+5

यह हमेशा व्यावहारिक नहीं है। जैसा कि मैंने उल्लेख किया है, रेलों में Rails.cache और I18n जैसे वैश्विक वस्तुएं हैं। –

0

क्या आपने फ़्लैश माना है? यह सत्र का उपयोग करता है लेकिन स्वचालित रूप से साफ़ हो जाता है।

-3

एप्लिकेशन/मॉडल/my_cacher.rb

class MyCacher 
    def self.result 
    @@result ||= begin 
     # do expensive stuff 
     # and cache in @@result 
    end 
    end 
end 

|| = वाक्य रचना मूल रूप से मतलब है "अगर @@ परिणाम नहीं के बराबर है तो निम्न कार्य करें" (यानी कुछ भी करने के लिए अभी तक सेट नहीं)। बस सुनिश्चित करें कि प्रारंभ/अंत ब्लॉक में अंतिम पंक्ति परिणाम लौट रही है।

अपने विचार/मॉडल/जो कुछ भी तुम सिर्फ समारोह संदर्भ जब आप इसे की आवश्यकता होगी में

तब:

MyCacher.result 

यह एक अनुरोध की अवधि के लिए महंगा कार्रवाई कैश होगा।

+4

यह उत्पादन मोड में ऐप इंस्टेंस (कई अनुरोध) के जीवनकाल के लिए कैश किया जाएगा। – cwninja

0

Memoisation?

this railscast के अनुसार यह प्रति अनुरोध संग्रहीत है।

+2

क्लास विधि पर ज्ञापन हर समय कैश करेगा। एक उदाहरण पर यादें उस उदाहरण के जीवनकाल के लिए कैश करेंगे। कक्षाओं पर अत्यधिक कैशिंग मेमोरी को ढकता है। मैंने इस गलती के उत्पादन बक्से को नीचे ले लिया है। – cwninja

4

वहाँ भी request_store मणि है।प्रलेखन से:

अपने आवेदन की Gemfile को यह पंक्ति जोड़ दें:

gem 'request_store' 

और स्टोर और डेटा (अनुरोध तक ही सीमित) को पुनः प्राप्त करने के लिए इस कोड का उपयोग करें:

# Set 
RequestStore.store[:foo] = 0 

# Get 
RequestStore.store[:foo] 
+0

मणि मूल रूप से पूरी समस्या हल करता है। मैंने कुछ उपयोग निर्देशों में जोड़ा है, लेकिन मूल रूप से इसके मुकाबले ज्यादा कुछ नहीं है। –

+0

आपको इस मणि को थ्रेड या प्यूमा जैसे थ्रेडेड सर्वर के साथ उपयोग नहीं करना चाहिए। – Papipo

+0

@Papipo इस मणि के लिए प्रलेखन थिन और प्यूमा जैसे थ्रेडेड सर्वरों के लिए 'थ्रेड.current' के कार्यात्मक विकल्प के रूप में स्पष्ट रूप से परिभाषित करता है। – James

1

सबसे में से एक लोकप्रिय विकल्प request_store मणि का उपयोग करना है, जो आपको अपने कोड के किसी भी हिस्से से वैश्विक स्टोर तक पहुंचने की अनुमति देता है। यह आपके डेटा को स्टोर करने के लिए Thread.current का उपयोग करता है, और प्रत्येक अनुरोध के बाद डेटा को साफ करने का ख्याल रखता है।

RequestStore[:items] = [] 

हालांकि ध्यान रखें, क्योंकि यह Thread.current का उपयोग करता है, यह एक मल्टी-थ्रेडेड वातावरण जहां अनुरोध के अनुसार एक से अधिक धागा है में ठीक से काम नहीं करेगा।

इस समस्या को रोकने के लिए, मैंने एक स्टोर लागू किया है जिसे उसी अनुरोध के लिए थ्रेड के बीच साझा किया जा सकता है। यह request_store_rails कहा जाता है, यह धागा सुरक्षित है, और उपयोग बहुत समान है:

RequestLocals[:items] = [] 
संबंधित मुद्दे