5

के बीच रेस स्थिति से निपटने के लिए कैसे करें मैंने एरलांग के संदेश उत्तीर्ण निर्माण का उपयोग करके एक बहु खिलाड़ी गेम (सटीक, 4 खिलाड़ी होने के लिए) बनाया है। मैं एक उदाहरण के रूप में दिए गए लिंक पर tictactoe खेल का पालन किया है, लेकिन क्या वास्तव में इसी तरह की है के रूप में खेल में दिखाया गया है का निर्माण गुजर संदेश है:फ़ंक्शन कॉल

मैं तो ejabberd मल्टी उपयोगकर्ता चैट रूम पर इस खेल को चलाने के लिए चुना है, मैं लिखा इसके लिए एक ejabberd हुक। लेकिन यदि आप उपरोक्त लिंक पर tictactoe.erl फ़ाइल में NewGameState को देखते हैं, तो आप पाएंगे कि को एक चर में पुनर्प्राप्त करने का कोई तरीका नहीं है।

तो मैंने मैनेशिया का उपयोग किया और इस मैनेशिया टेबल से उत्पन्न प्रत्येक नए गैमेस्टेट को लिखा। अब मेरे ejabberd हुक के अंदर मैं अपने गेम फ़ंक्शन को कॉल करता हूं (यानी प्रत्येक कॉल पर मॉड्यूल की एक श्रृंखला -> "gen_server, game_modules, mnesia_modules" निष्पादित की जाती हैं) और गेम फ़ंक्शन के कॉल के ठीक नीचे हुक के अंदर मैं मेनेसिया टेबल से पढ़ रहा हूं gamestate इस प्रकार के लिए (यहाँ समारोह myMessage ejabberd हुक अंदर समारोह है):

myMessage({#message = Msg, C2SState})-> 
    some_other_module:game_func(Args), 
    State=mnesia_module:read(key), 

    {Msg, C2SState}; 
myMessage(Acc) -> 
    Acc. 

अब मेरी समस्या यह है कि पढ़ने के लिए आपरेशन मुझे एक खाली टेबल दे रहा है जब निष्पादन के आदेश

some_other_module:game_func(Args), 
GameState=mnesia_module:read(key), 
है

और जब मैं इन दो पंक्तियों के बीच timer:sleep/1 के रूप में देरी डालता हूं

some_other_module:game_func(Args), 
timer:sleep(200) 
GameState=mnesia_module:read(key), 

मैं मुझे सुझाव है कि लाइन में पढ़ने आपरेशन

GameState=mnesia_module:read(key), 

प्रदर्शन किया जा रहा है GameState का सही मूल्य मिल रहा है इस प्रकार: elow (मूल्य 200 विभिन्न मूल्यों के साथ कुछ परीक्षण के बाद बेतरतीब ढंग से चुना जाता है)/some_other_module:game_func(Args) (जो मॉड्यूल की एक श्रृंखला है -> "gen_server, game_modules, mnesia_modules") से पहले निष्पादित किया गया है, मैनेशिया मॉड्यूल निष्पादित करने और गेमस्टेट को मेनेसिया टेबल में लिखने में सक्षम है।

मैं इस समस्या को कैसे हल कर सकता हूं क्योंकि मैं timer:sleep/1 का उपयोग नहीं करना चाहता क्योंकि यह भरोसेमंद समाधान नहीं है।

क्या कोई मुझे यहां एक काम का सुझाव दे सकता है। मेरा मतलब यह है कि क्या कोई मुझे हंस के अंदर गेमस्टेट को मैनेशिया के अलावा किसी अन्य माध्यम से पुनर्प्राप्त करने का एक तरीका सुझा सकता है, इसलिए मेरे पास दौड़ की स्थिति नहीं है।

या तो कोई तरीका है कि ejabberd कुछ कार्यक्षमता प्रदान करता है जिसका मैं यहां उपयोग कर सकता हूं?

अग्रिम धन्यवाद।

+0

क्या आप मेनेसिया का उपयोग कर रहे हैं: dirty_ * functions? – Pouriya

+0

नहीं @Pouriya मैं mnesia का उपयोग कर रहा हूं: कुछ लिखने के लिए लिखने के लिए लिखें/लिखें जबकि कुछ_other_module: game_func (Args) चल रहा है और मैनेशिया: जब डेटास्टेट = mnesia_module: read (key) कहा जाता है तो डेटा को पढ़ने के लिए पढ़ें/3 फ़ंक्शन। –

+0

क्या आप कोड दिखा सकते हैं? – Pouriya

उत्तर

1

मैं अपने लिए काम करने वाले समाधान देने की कोशिश कर रहा हूं। उम्मीद है कि यह किसी की मदद करता है।

यहाँ मैं क्या किया है:

सबसे पहले मैं तस्वीर से mnesia हटा दिया।

मैं पहली बार आधार मॉड्यूल की Pid पंजीकृत जैसे ही यह start/2 समारोह के अंदर बनाई गई है (यदि आप प्रश्न में दिए गए लिंक पर tictactoe.erl वर्तमान के बारे में सोच सकते हैं) और फिर मुझे लगता है कि मॉड्यूल के अंदर एक get_gs/0 समारोह बनाया इस प्रकार केवल GameState पुनः प्राप्त करने के (server उर्फ ​​मैं Pid रजिस्टर करने के लिए इस्तेमाल किया है है):

get_gs()-> 
    server ! {get_gs, self()}, 
    receive 
     GameState -> 
      GameState 
    end. 

और फिर loop() समारोह के अंदर मेरे पास है:

{ get_gs, From } -> 
      From ! GameState, 

      loop(FirstPlayer, SecondPlayer, CurrentPlayer, GameState) 

फिर एक मॉड्यूल gen_server वास्तुकला को लागू करने के लिए बनाया और निम्न क्रम में एक समारोह (जहां -> समारोह ए की तरह कहता है> बी ए से मतलब है मैं बी फोन का प्रतिनिधित्व करता है) कहा जाता है:

My custom hook on ejabberd->gen_server based module->gameclient:get_gs/0->gameserver:get_gs/0->tictactoe:get_gs/0 

और मैं वर्तमान GameState मिला है।

आपके मूल्यवान सुझाव के लिए @Nathaniel Waisbrot धन्यवाद।

+0

अच्छा लग रहा है! जब आप थोड़ी अधिक जटिलता के लिए तैयार महसूस करते हैं, तो मैं दृढ़ता से ओटीपी संरचनाओं (पर्यवेक्षक, gen_server, gen_statem) का उपयोग करने की सलाह देता हूं। उनके चारों ओर अपने सिर को पाने में कुछ समय लगता है लेकिन वे आश्चर्यजनक शक्तिशाली उपकरण हैं जिन्हें आप _constantly_ का उपयोग करेंगे। (इसके विपरीत, मेनेसिया सीखने के लिए भी जटिल है लेकिन केवल विशिष्ट परिस्थितियों में उपयोगी है।) –

+0

हाँ निश्चित रूप से मैं ओटीपी संरचनाओं को देखूंगा। मदद के लिए धन्यवाद। चेयर –

6

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

हालांकि, यहां एक सरल उपाय आप समस्या के बारे में सोचने मदद मिल सकती है:

सबसे पहले आपके नोड्स master से एक फोन करते हैं। मास्टर नोड पर, एक gen_server शुरू करें जो गेम-स्टेट को संभालता है। अब, कोई भी जो गेम-स्टेट को पढ़ना या लिखना चाहता है उसे rpc:call/4 मास्टर नोड (जब तक कि वे पहले से ही नहीं हैं) को gen_server:call/2 में बनाना चाहते हैं। अब खेल राज्य के साथ सभी बातचीत तुल्यकालिक है।

यदि आप गेम स्थिति को एक सेकंड से अधिक बार अपडेट नहीं करते हैं, तो इस समाधान को आपके लिए काफी अच्छा काम करना चाहिए। यदि गेम स्वतंत्र हैं, तो प्रत्येक गेम एक अलग gen_server है।

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