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

रेल्स ऐप्स को सुव्यवस्थित करना: ग्लोबल कॉन्टेक्स्ट के लिए एक कॉम्पैक्ट एक्टिवसपोर्ट मॉड्यूल

आम तौर पर, ग्लोबल वेरिएबल्स खराब होते हैं। लेकिन कभी-कभी, सही जगह पर एक ग्लोबल आपके कोड को बहुत सरल बना सकता है।

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

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

आपको कुछ ऐसा चाहिए जो ग्लोबल हो, लेकिन सिर्फ आपकी रिक्वेस्ट के लिए।

सादा रूबी तरीका

आमतौर पर, आप इसे Thread.current[] के साथ होते हुए देखेंगे। यह इस तरह दिखता है:

Thread.current[:current_user] = user

यह काफी सरल है। यह एक अच्छा समाधान है। लेकिन इसकी दो बड़ी कमियां हैं:

  1. कोई गलती से आपके डेटा को ओवरराइट कर सकता है।

    क्या होगा अगर दो लोगों ने एक ही कुंजी चुनी? आप एक-दूसरे के डेटा पर रौंद देंगे। और अगर आप यूजर्स जैसी कोई चीज स्टोर कर रहे हैं, तो यह गंभीर रूप से खराब होगा। आपके अपने ऐप्स में, यह शायद कोई समस्या नहीं होगी। लेकिन अगर आप जेम्स लिख रहे हैं, या आपका रेल्स ऐप बड़ा और गड़बड़ है, तो यह कुछ ऐसा है जिसके बारे में आपको सोचने की ज़रूरत है।

  2. यह अच्छी तरह से संरचित नहीं है।

    Thread.current[] सिर्फ डेटा का एक बड़ा बैग है। आप इसे आसानी से दस्तावेज़ नहीं कर सकते। यदि आप जानना चाहते हैं कि आप इससे क्या निकाल सकते हैं, तो आपको यह खोजना होगा कि आपने इसमें क्या डाला।

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

तो, क्या Thread.current[] से बेहतर कोई समाधान है? जैसा कि आप कल्पना कर सकते हैं, रेल्स खुद बहुत सारे रिक्वेस्ट-लोकल डेटा को मैनेज करता है। और गुडीज़ का जो बॉक्स एक्टिवसपोर्ट है, उसके पास फॉलो करने के लिए एक अलग पैटर्न है।

रेल्स तरीका

यदि आप एक्टिवसपोर्ट के माध्यम से खुदाई करते हैं, तो आप ActiveSupport::PerThreadRegistry में आ सकते हैं। आप शायद नाम से बता सकते हैं कि यह वही है जिसकी हम तलाश कर रहे हैं।

ActiveSupport::PerThreadRegistry के साथ, पहले का उदाहरण इस तरह दिखेगा:

class RequestRegistry
  extend ActiveSupport::PerThreadRegistry
  attr_accessor :current_user, :current_permissions
end

RequestRegistry.current_user = user
RequestRegistry.current_user # => user

यह थोड़ा सा अधिक काम है। लेकिन ActiveSupport::PerThreadRegistry के साथ:

  • आपके पास डॉक्यूमेंटेशन रखने की जगह है। आपकी क्लास को देखने वाला कोई भी व्यक्ति ठीक-ठीक जान जाएगा कि आप किस ग्लोबल डेटा की उम्मीद कर रहे हैं, और वे किस ग्लोबल डेटा का उपयोग कर सकते हैं।

  • आपको एक API मिलता है जो अच्छा दिखता है। वास्तव में, यह ऐसा दिखता है जैसे आप सिर्फ क्लास वेरिएबल सेट कर रहे हैं। यदि आपको थ्रेड्स के बारे में चिंता नहीं करनी होती तो आप शायद यही करते।

  • क्लास पर आपके द्वारा सेट किया गया कोई भी डेटा नेमस्पेस्ड होगा। आपको RequestRegistry.current_user के PhoneNumberApiRegistry.current_user से टकराने के बारे में चिंता करने की ज़रूरत नहीं है, उन्हें पूरी तरह से अलग माना जाता है।

रेल्स ActiveSupport::PerThreadRegistry का आंतरिक रूप से उपयोग करता है, एक्टिवरिकॉर्ड कनेक्शन हैंडलिंग, EXPLAIN क्वेरीज़ स्टोर करने, और ActiveSupport::Notifications जैसी चीजों के लिए। इसलिए यदि आप PerThreadRegistry की शक्ति के अधिक अच्छे उदाहरण ढूंढ रहे हैं, तो रेल्स खुद शुरू करने के लिए एक शानदार जगह है।

जब थ्रेड्स और रिक्वेस्ट मेल नहीं खाते

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

आप वह कर सकते हैं जो रेल्स करता है, और उन चीजों को साफ करें जिन्हें आप PerThreadRegistry में डालते हैं जब आप उनके साथ काम कर लेते हैं। आप जो उसमें डालते हैं उस पर निर्भर करते हुए, आप वैसे भी ऐसा कर रहे होंगे।

टिप्पणियों में, मैटबी एक आसान समाधान की ओर इशारा करता है: request_store। यह Thread.current[] की तरह कार्य करता है, लेकिन प्रत्येक रिक्वेस्ट के बाद खुद को साफ कर लेता है।

यह किसी के लिए PerRequestRegistry बनाने का द्वार खुला छोड़ देता है, जो request_store की सुरक्षा को PerThreadRegistry के API के साथ जोड़ता है। अगर किसी ने यह पहले ही कर लिया है, तो मुझे इसके बारे में सुनना अच्छा लगेगा!

इसे आजमाएं

ग्लोबल डेटा खराब हो सकता है। बहुत सारे ग्लोबल जल्दी से अनुरक्षणीय कोड की ओर ले जा सकते हैं।

लेकिन अगर पूरे रिक्वेस्ट के लिए एक केंद्रीय स्थान पर डेटा रखना समझ में आता है, तो Thread.current[] से आगे बढ़ें। ActiveSupport::PerThreadRegistry या request_store को एक शॉट दें। अगर कुछ नहीं, तो यह ग्लोबल डेटा से निपटने को थोड़ा कम जोखिम भरा बना देगा।

  1. डेटा सेंटर क्या है? डेटा सेंटर क्या है?

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

  1. हैकर्स समझौता की गई वेबसाइटों का शोषण कैसे करते हैं हैकर्स समझौता की गई वेबसाइटों का शोषण कैसे करते हैं

    2017 हैकर्स का वर्ष था। कंटेंट मैनेजमेंट सिस्टम, ई-कॉमर्स पोर्टल, डेटा उल्लंघन से लेकर वित्तीय संस्थानों की हैक की गई वेबसाइटों तक, साइबर अपराध हर गुजरते साल के साथ बढ़ रहा है। 2017 में भारी साइबर हमले देखे गए जैसे बड़े पैमाने पर वित्तीय डेटा चोरी इक्विफैक्स डेटा ब्रीच, वानाक्राई साइबर अटैक जो 2017

  1. बिग डेटा के साथ क्या गलत हो सकता है? प्रमुख जोखिम और शमन रणनीतियाँ बिग डेटा के साथ क्या गलत हो सकता है? प्रमुख जोखिम और शमन रणनीतियाँ

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