एक घटना संचालित वास्तुकला में प्रारंभिक स्थिति को कैसे संभालना है?


33

एक में घटना चालित वास्तुकला प्रत्येक घटक केवल कार्य करता है एक घटना प्रणाली के माध्यम से भेजा जाता है जब।

ब्रेक पेडल और ब्रेक लाइट के साथ काल्पनिक कार की कल्पना करें।

  • ब्रेक लाइट बदल जाता है पर जब यह एक प्राप्त करता है brake_on घटना, और बंद जब यह एक प्राप्त करता है brake_off घटना।
  • ब्रेक पेडल एक ब्रेक_न घटना भेजता है जब इसे दबाया जाता है, और एक ब्रेक_ऑफ घटना जब इसे जारी किया जाता है।

यह सब ठीक है और अच्छा है, जब तक आपके पास स्थिति नहीं है जहां कार को चालू किया जाता है ब्रेक पेडल के साथ पहले से ही नीचे दबाया जाता है । चूंकि ब्रेक लाइट को कभी ब्रेक_ऑन इवेंट नहीं मिला , इसलिए यह बंद रहेगा - स्पष्ट रूप से एक अवांछनीय स्थिति। डिफ़ॉल्ट रूप से ब्रेक लाइट चालू करने से स्थिति उलट हो जाती है।

इस problem प्रारंभिक राज्य समस्या ’को हल करने के लिए क्या किया जा सकता है?

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

EDIT 2: @ gbjbaanb के उत्तर के अलावा , मैं एक ऐसी प्रणाली के लिए जा रहा हूँ जिसमें:

  • प्रारंभिक ब्रेक पेडल, आरंभीकरण के बाद, अपने राज्य के साथ एक घटना भेजता है, और
  • प्रारंभिक ब्रेक लाइट, आरंभीकरण के बाद, ब्रेक पेडल से एक राज्य घटना का अनुरोध करते हुए एक घटना भेजता है।

इस समाधान के साथ, घटकों के बीच कोई निर्भरता नहीं है, कोई दौड़ की स्थिति नहीं है, बासी जाने के लिए कोई संदेश कतार नहीं है, और कोई 'मास्टर' घटक नहीं हैं।


2
पहली बात जो मन में आती है वह है "सिंथेटिक" घटना (इसे कॉल करें initialize) जिसमें आवश्यक सेंसर डेटा शामिल है।
14

क्या पेडल को ब्रेक_पेनल_ऑन इवेंट नहीं भेजना चाहिए, और वास्तविक ब्रेक को ब्रेक_ऑन इवेंट भेजना चाहिए? मैं नहीं चाहूंगा कि मेरी ब्रेक लाइट आए, अगर ब्रेक काम नहीं कर रहा था।
बीडीएसएल

3
क्या मैंने उल्लेख किया है कि यह एक काल्पनिक उदाहरण था? :-) सवाल को छोटा और बिंदु तक रखना बहुत सरल है।
फ्रैंक केल

जवाबों:


32

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

इसलिए, जबकि रनिंग सिस्टम स्वयं की देखभाल करेगा, हमें प्रत्येक घटक को स्वयं को शुरू करने के लिए कहने के लिए एक तरीका चाहिए, और हमारे पास पहले से ही घटक पंजीकरण में एक ऐसी चीज है, अर्थात स्टार्टअप पर कोर सिस्टम को प्रत्येक घटक को सूचित करना होगा कि यह है अब पंजीकृत (या प्रत्येक घटक को अपने विवरण वापस करने के लिए कहेंगे ताकि इसे पंजीकृत किया जा सके)। यह वह चरण है जिस पर घटक अपने स्टार्टअप कार्य कर सकता है, और संदेश भेज सकता है जैसा कि वह सामान्य ऑपरेशन में करेगा।

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

समस्या तब स्टार्टअप निर्भरता में से एक बन जाती है, जैसे कि अगर ब्रेक लाइट अभी तक पंजीकृत नहीं है, तो यह संदेश प्राप्त नहीं करेगा, लेकिन जब तक कोर सिस्टम ने अपना स्टार्टअप, पंजीकरण और चेक रूटीन पूरा नहीं कर लिया, तब तक इन सभी संदेशों को कतार में लगाकर आसानी से हल किया जा सकता है। ।

सबसे बड़ा फ़ायदा यह है कि आरंभीकरण को संभालने के लिए किसी विशेष कोड की आवश्यकता नहीं है, सिवाय इसके कि आपको पहले से ही लिखना है (ठीक है, यदि ब्रेक पेडल घटनाओं के लिए आपका संदेश-भेजना ब्रेक-पेडल हैंडलर में है तो आपको कॉल करना होगा कि आपके प्रारंभिककरण में भी , लेकिन यह आम तौर पर एक समस्या नहीं है जब तक कि आपने उस कोड को हैंडलर तर्क से भारी रूप से नहीं लिखा है) और घटकों के बीच कोई बातचीत नहीं है सिवाय इसके कि वे पहले से ही एक दूसरे को सामान्य रूप में भेजते हैं। संदेश पासिंग आर्किटेक्चर इस वजह से बहुत अच्छे हैं!


1
मुझे आपका उत्तर पसंद है, क्योंकि यह सभी घटकों को अलग रखता है - यह इस वास्तुकला को चुनने का सबसे महत्वपूर्ण कारण था। हालांकि, वर्तमान में कोई वास्तविक 'मास्टर' घटक नहीं है जो सिस्टम को तय करता है कि वह 'प्रारंभिक' स्थिति में है - सब कुछ बस चलना शुरू हो जाता है। परिणामस्वरूप मेरे प्रश्न में समस्या है। एक बार जब मास्टर फैसला करता है कि सिस्टम चल रहा है, तो यह सभी घटकों को एक 'सिस्टम इनिशियलाइज्ड' ईवेंट भेज सकता है, जिसके बाद हर कंपोनेंट उसकी स्थिति को प्रसारित करना शुरू कर देता है। समस्या सुलझ गयी। धन्यवाद! (अब मैं सिर्फ इस समस्या से कैसे
बचा जाऊं

स्टेटस-अपडेट डिस्पैचर होने के बारे में कैसे प्रत्येक ऑब्जेक्ट से प्राप्त सबसे हालिया अपडेट का ट्रैक रखता है, और जब भी कोई नया सब्सक्रिप्शन अनुरोध प्राप्त होता है, तो क्या उसने नए सब्सक्राइबर को सबसे हाल के अपडेट्स को पंजीकृत इवेंट स्रोतों से प्राप्त किया है?
सुपरकैट

उस स्थिति में आपको यह भी ध्यान रखना होगा कि इवेंट कब समाप्त होंगे। सभी घटनाओं को पंजीकृत करने वाले किसी भी नए घटकों के लिए हमेशा के लिए रखने के लिए उत्तरदायी नहीं हैं।
फ्रैंक केल

@spaceknarf अच्छी तरह से, इस मामले में जहां "सब कुछ बस चलने लगता है" आप घटकों में निर्भरता का निर्माण नहीं कर सकते हैं, इसलिए पैडल प्रकाश के बाद शुरू होता है, आपको बस उन्हें उसी क्रम में शुरू करना होगा, हालांकि मुझे लगता है कि कुछ उन्हें चलाना शुरू कर रहा है, इसलिए चलाएं उन्हें 'सही' क्रम में (उदाहरण के लिए linux स्टार्टअप इनिट स्क्रिप्ट्स सिस्टमड से पहले जहां पहले शुरू करने वाली सेवा को 1.xxx कहा जाता है और 2 को 2.xxx आदि कहा जाता है)।
gbjbaanb

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

4

आपके पास एक इनिशियलाइज़ इवेंट हो सकता है जो लोड / स्टार्टअप पर उचित रूप से स्टेट्स सेट करता है। यह सरल सिस्टम या प्रोग्राम के लिए वांछनीय हो सकता है जिसमें कई हार्डवेयर टुकड़े शामिल नहीं होते हैं, हालांकि कई भौतिक घटकों के साथ अधिक जटिल प्रणालियों के लिए जैसा कि आप एक ही जोखिम चलाते हैं जैसा कि बिल्कुल भी प्रारंभ नहीं होता है - अगर आपके संचार में "ब्रेक ऑन" ईवेंट छूट गया है या खो गया है सिस्टम (उदाहरण के लिए, CAN आधारित प्रणाली) आप अनजाने में अपने सिस्टम को पीछे की ओर सेट कर सकते हैं जैसे कि आपने इसे ब्रेक डिप्रैस्ड के साथ शुरू किया हो। अधिक नियंत्रक आपके पास हो सकते हैं, जैसे कि कार के साथ, उच्च संभावना कुछ छूट गई है।

इसका जवाब देने के लिए, आप "ब्रेक ऑन" लॉजिक को बार-बार "ब्रेक ऑन" ईवेंट पर भेज सकते हैं। शायद हर १/१०० सेकंड या कुछ और। मस्तिष्क वाला आपका कोड इन घटनाओं को सुन सकता है और उन्हें प्राप्त करते समय "ब्रेक ऑन" ट्रिगर कर सकता है। 1 / 10sec "सिग्नल पर ब्रेक" प्राप्त नहीं करने के बाद यह एक आंतरिक "ब्रेक_ऑफ़" घटना को ट्रिगर करता है।

विभिन्न घटनाओं में काफी अलग समय की आवश्यकताएं होंगी। एक कार में, आपके चेक फ्यूल लाइट (जहां एक मल्टीसेकंड देरी शायद स्वीकार्य है) या अन्य कम महत्वपूर्ण प्रणालियों की तुलना में आपके ब्रेक लाइट को बहुत तेज़ होना चाहिए ।

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

किसी भी तरह से, एक भौतिक प्रणाली के साथ, आप सही ढंग से प्राप्त / संसाधित होने वाली किसी एक घटना पर भरोसा नहीं करना चाहते हैं। नेटवर्क सिस्टम पर कनेक्टेड माइक्रोकंट्रोलर्स में अक्सर इस वजह से "आई एम लिव" टाइमआउट होता है।


एक भौतिक प्रणाली में आप एक तार चलाते हैं और बाइनरी लॉजिक का उपयोग करते हैं: हाई ब्रेक डिप्रेस्ड है और LOW ब्रेक
शाफ़्ट फ्रीक

@ratchetfreak इस तरह की चीज़ों के लिए बहुत सारी संभावनाएँ हैं। शायद एक स्विच जो संभाल सकता है। कई अन्य सिस्टम ईवेंट हैं जिन्हें केवल नियंत्रित नहीं किया गया है।
एंडरलैंड

1

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

जब सिस्टम शुरू किया गया था, तब तक यह दबाव की घटनाओं को दूर करने के लिए शुरू हो जाएगा।


1

यदि आपका केवल राज्य सूचना पास करने का माध्यम घटनाओं के माध्यम से है, तो आप मुसीबत में हैं। इसके बजाय, आपको दोनों में सक्षम होना चाहिए:

  1. ब्रेक पेडल की वर्तमान स्थिति को क्वेरी करें, और
  2. ब्रेक पेडल से "राज्य परिवर्तित" घटनाओं के लिए रजिस्टर करें।

ब्रेक लाइट को ब्रेक पेडल के पर्यवेक्षक के रूप में देखा जा सकता है। दूसरे शब्दों में, ब्रेक पैडल ब्रेक लाइट के बारे में कुछ भी नहीं जानता है, और इसके बिना काम कर सकता है। (इसका मतलब यह है कि ब्रेक पेडल की कोई भी धारणा लगातार ब्रेक लाइट के लिए एक "प्रारंभिक स्थिति" घटना भेजती है, इसकी कल्पना की गई है।)

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

फिर, ब्रेकिंग सूचनाओं को तीन तरीकों में से एक में लागू किया जा सकता है:

  1. पैरामीटरलेस "ब्रेकिंग पेडल स्टेट चेंज" घटनाओं के रूप में
  2. "ब्रेकिंग पैडल अब उदास है" की एक जोड़ी के रूप में और "ब्रेकिंग पैडल अब जारी किया गया है" इवेंट
  3. एक "उदास" या "जारी" पैरामीटर के साथ "नए ब्रेकिंग पेडल राज्य" घटना के रूप में।

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


0

एक इवेंट-संचालित प्रणाली (जो मैं वर्तमान में उपयोग और प्यार करता हूं) में, मुझे चीजों को जितना संभव हो उतना कम रखने के लिए महत्वपूर्ण लगता है। तो उस विचार को ध्यान में रखते हुए, हम सही तरीके से प्रस्तुत करते हैं।

कुछ डिफ़ॉल्ट स्थिति होना महत्वपूर्ण है। आपका ब्रेक लाइट 'ऑफ' की डिफ़ॉल्ट स्थिति को ले जाएगा और आपका ब्रेक पैडल 'अप' की डिफ़ॉल्ट स्थिति को ले जाएगा। उसके बाद कोई भी बदलाव एक घटना होगी।

अब अपने प्रश्न का समाधान करने के लिए। कल्पना करें कि आपके ब्रेक पेडल को इनिशियलाइज़ किया जा रहा है और दबाया जा रहा है, तो ईवेंट फायर हो जाता है, लेकिन ईवेंट को प्राप्त करने के लिए अभी तक कोई ब्रेक लाइट नहीं है। मैंने किसी भी लॉजिक को इनिशियलाइज़ करने से पहले एक अलग स्टेप के रूप में ऑब्जेक्ट्स (जहाँ ईवेंट श्रोताओं को इनिशियलाइज़ किया जाता है) के निर्माण को अलग करना सबसे आसान पाया है । जैसा कि आप वर्णित किसी भी दौड़ की स्थिति को रोकेंगे।

मुझे यह भी अजीब लगता है कि प्रभावी रूप से एक ही चीज के लिए दो अलग-अलग घटनाओं का उपयोग करना । brake_offऔर एक पैरामीटर के साथ brake_onसरलीकृत किया जा सकता है । आप सहायक डेटा जोड़कर अपनी घटनाओं को इस तरह सरल बना सकते हैं।e_brakebool on


0

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

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

  1. हर प्रसारण कार्यक्रम में एक नाम की आवश्यकता होती है
  2. किसी भी समय, एक प्रसारण कार्यक्रम के प्रेषक के पास एक निर्दिष्ट नाम के साथ केवल एक सक्रिय प्रसारण हो सकता है
  3. घटना के कारण होने वाला प्रभाव निष्प्राण होना चाहिए

प्रसारण नाम को घटक स्थापना के समय के दौरान घोषित किया जाना चाहिए। यदि कोई घटक पिछले एक को संसाधित करने से पहले उसी नाम के साथ दूसरा प्रसारण भेजता है, तो नया प्रसारण पिछले वाले को अधिलेखित कर देता है। अब आपके पास एक स्थिर इनबॉक्स आकार सीमा हो सकती है, जिसे कभी भी एक निश्चित आकार से अधिक नहीं होने की गारंटी दी जा सकती है और सदस्यता तालिका के आधार पर इसे पूर्व निर्धारित किया जा सकता है।

अंत में, आपको एक प्रसारण संग्रह भी चाहिए। प्रसारण संग्रह एक तालिका है जो प्रत्येक प्रसारण नाम से अंतिम घटना रखती है। नए घटक जो अभी स्थापित किए गए हैं, इसका इनबॉक्स प्रसारण आर्काइव के संदेशों के साथ पूर्वनिर्मित होगा। संदेश इनबॉक्स की तरह, प्रसारण संग्रह में स्थिर आकार भी हो सकता है।

इसके अतिरिक्त, स्थिति से निपटने के लिए जहां संदेश राउटर स्वयं ऑफ़लाइन है, आपको संदेश आउटबॉक्स की भी आवश्यकता है। संदेश आउटबॉक्स उस घटक का हिस्सा है जो अस्थायी रूप से आउटगोइंग संदेश रखता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.