2014-04-01 9 views
10

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

लेकिन क्या होता है अगर अभिनेता किसी संदेश से जुड़े कार्य को करने का भविष्य बनाता है? चूंकि भविष्य एसिंक है, इसलिए अभिनेता अगले कई संदेशों को संसाधित करना शुरू कर सकता है जबकि पूर्व संदेश से जुड़ा भविष्य अभी भी चल रहा है। क्या यह संभावित रूप से दौड़ की स्थिति पैदा नहीं करेगा? लंबे समय तक चलने वाले कार्यों को करने के लिए एक अभिनेता की प्राप्त() विधि के भीतर एक सुरक्षित रूप से वायदा का उपयोग कैसे कर सकता है?

+0

क्या आपका मतलब है कि भविष्य के साथ जुड़ी कार्रवाई अभिनेता के लिए आंतरिक चर पर चलती है? फिर हाँ, यह दौड़ की स्थिति है। –

उत्तर

1

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

मैन्युअल रूप से राज्य की देखभाल करने के बजाय आप akka's FSM का उपयोग करने पर विचार करना चाहेंगे ताकि आपको क्या बदलता है इसकी एक बहुत साफ तस्वीर मिल जाए। जब मैं अधिक जटिल प्रणालियों से निपट रहा हूं तो मैं बदसूरत चर के लिए इस दृष्टिकोण को प्राथमिकता से पसंद करता हूं।

16

किसी अभिनेता के भीतर वायदा का उपयोग करने का सबसे सुरक्षित तरीका भविष्य में केवल pipeTo का उपयोग करना है और इसके परिणाम को एक अभिनेता (संभवतः एक ही अभिनेता) को एक संदेश के रूप में भेजना है।

import akka.pattern.pipe 

object MyActor { 

    def doItAsynchronously(implicit ec: ExecutionContext): Future[DoItResult] = { 
    /* ... */ 
    } 

} 

class MyActor extends Actor { 

    import MyActor._  
    import context.dispatcher 

    def receive = { 
    case DoIt => 
     doItAsynchronously.pipeTo(self) 
    case DoItResult => 
     // Got a result from doing it 
    } 

} 

यह सुनिश्चित करता है कि आप अभिनेता के भीतर किसी भी राज्य को म्यूट नहीं करेंगे।

+2

+1, और यदि यह इस उत्तर से स्पष्ट नहीं था, तो 'doItAsynchronously' को * अभिनेता के किसी भी राज्य को म्यूट नहीं करना चाहिए। असल में, यदि आप उस फ़ंक्शन को किसी साथी ऑब्जेक्ट में ले जा सकते हैं (या ऐसा कुछ भी जिसके पास आपके अभिनेता के 'यह' तक पहुंच नहीं है), तो इसके बारे में ईमानदार रखना आसान होगा। –

+0

अच्छा बिंदु, मैं इसे स्पष्ट करने के लिए अपना उदाहरण संपादित करूंगा। – Ryan

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