2011-04-05 8 views
37

Akka में, क्या "टाइप किए गए अभिनेता" एपीआई का उपयोग करने के अलावा किसी विशिष्ट स्थिर प्रकार के होने के लिए कलाकारों को संदेशों को प्रतिबंधित करने का कोई तरीका है जो आरपीसी शैली प्रोग्रामिंग मॉडल का उपयोग करते हैं?अभिनेता संदेशों को विशिष्ट प्रकारों तक सीमित कैसे करें?

क्या मैं अभिनेता सीमाओं पर स्थिर प्रकार की सुरक्षा को फेंकने के बिना अक्का के साथ संदेश गुजरने वाली शैली का उपयोग कर सकता हूं?

उदाहरण के लिए, मैं इस तरह कोड का उपयोग करना चाहते हैं:

sealed abstract class FooMessage 
case object Foo extends FooMessage 
case object Bar extends FooMessage 

class FooActor extends Actor[FooMessage] { 
    def receive = { 
    case Foo =>() // OK 

    // Would raise a compiler error: 
    // case s: String => error("Can't happen, String is not a subtype of FooMessage") 

    } 
} 

val fooActor = actorOf[FooActor] 
fooActor ! Foo // OK 

// Won't compile: 
fooActor ! "Hello" 

शायद एक कुछ आधार विशेषता, आदि का विस्तार या एक निर्माण की तरह Either प्रणाली के स्तर संदेशों के लिए अनुमति देने के लिए (Exit है करने के लिए होगा)।

उत्तर

25

तो फिर तुम अभिनेता रेफरी, जो काफी कुछ का मूल्य कम होगा में संदेश प्रकार सांकेतिक शब्दों में बदलना होगा:

हालांकि, चैनलों का उपयोग कर, यह अभी भी संभव stdlib के साथ दृढ़ता से टाइप किया अभिनेताओं बनाने के लिए अभिनेता रजिस्ट्री की तरह।

इसके अलावा, "बनने" जैसे शक्तिशाली यांत्रिकी (जो कि अभिनेता मॉडल के लिए मूलभूत है) के साथ संदेश टाइप करना कम मूल्यवान है।

चूंकि जब कोई संदेश वर्तमान व्यवहार से मेल नहीं खाता है, तो अकाका स्मृति को रिसाव नहीं करता है, इसलिए "गलत" अभिनेता को "गलत" संदेश भेजने का जोखिम नहीं होता है।

इसके अलावा, अभिनेता प्रकृति गतिशील होते हैं, इसलिए यदि आप उन्हें स्थिर बनाना चाहते हैं, तो टाइपेडएक्टर (जो आरपीसी नहीं है, यह आरपीसी के रूप में नियमित अभिनेता के रूप में है, शून्य विधियां हैं! कॉल, भविष्य वापसी प्रकार है !!! और अन्य रिटर्न प्रकारों पर आधारित हैं !!)

आम अभ्यास यह घोषित करना है कि अभिनेता के साथी वस्तु में एक अभिनेता क्या संदेश प्राप्त कर सकता है, जो यह जानना बहुत आसान बनाता है कि यह क्या प्राप्त कर सकता है।

क्या इससे मदद मिलती है?

+2

उपयोगी उत्तर के लिए धन्यवाद। क्या आपने (अक्का टीम) ने कभी भी अभिनेताओं को संदेशों में टाइप बाधाओं को जोड़ने की कोशिश की है, या क्या इसे कभी भी उपयोगी विचार नहीं माना गया है? – mkneissl

+2

अतीत में सूची के बारे में बात की गई है, लेकिन हम हमेशा एक ही स्थान पर समाप्त होते हैं, कि टाइपेडएक्टर उस उपयोग के लिए है, और अभिनेता कुल गतिशील व्यवहार के लिए है। यदि आप अधिक नियंत्रण में महसूस करना चाहते हैं तो आप ActorRef के शीर्ष पर अपने स्वयं के अमूर्तता के साथ प्रयोग कर सकते हैं। क्या उससे मदद हुई? चीयर्स, √ –

23

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

object TypedActor { 

    def apply[A](fun: PartialFunction[A, Any]): OutputChannel[A] = { 
    val sink = new SyncVar[Channel[A]] 
    actor { 
     val in = new Channel[A](self) 
     sink set in 
     loop { 
     in react { case any => reply(fun(any)) } 
     } 
    } 
    sink.get 
    } 

} 

sealed abstract class FooMessage 
case object Foo extends FooMessage 
case object Bar extends FooMessage 

object Test { 

    val fooActor = TypedActor[FooMessage]{ 
    case Foo => println("OK") 
    } 

    fooActor ! Foo 
    fooActor ! "Hello!" // doesn't compile -> Type mismatch; found: String("Hello!"); required: FooMessage; 

} 
2

असल में एक अभिनेता को प्रतिबंधित करना इनपुट के रूप में केवल एक ही प्रकार के लिए बहुत उपयोगी नहीं है। मेरे दिमाग में और अधिक उपयोगी क्या है सख्ती से टाइप किए गए तरीके से संभावित इनपुट सूचीबद्ध करना।

case class Contact[T](...) 
case class Signal[T](contact:Contact[T], data:T) 

आपके मामले में इंटरफ़ेस एक भी इनपुट संपर्क के होते हैं::

val FooInput = contact[FooMessage]("FooInput") 

संकेतों के SynapseGrid ढांचे से निपटने के भीतर

अभिनेताओं में से सख्ती से टाइप किया आदानों के लिए एक दृष्टिकोण (SynapseGrid) नहीं है बिल्डर के साथ परिभाषित किया गया है:

class FooActorBuilder extends SystemBuilder { 
    inputs(FooInput, OtherInput) 
    FooInput.foreach(fooMessage =>() //OK 
) 
    OtherInput.foreach(...) 
} 

स्पष्ट रूप से एक असंगत प्रकारों के साथ सिग्नल का निर्माण नहीं कर सकता। इस प्रकार हमने समय की जांच संकलित की है। SynapseGrid में सिग्नल और संपर्कों के साथ काम करने के लिए एक डीएसएल है।उदाहरण के लिए, बाहर से फू या बार भेजने के लिए:

val SomeOtherContact = contact[Boolean]("SomeOtherContact") 
SomeOtherContact.map(flag => if(flag) Foo else Bar) >> FooInput 
पाठ्यक्रम एक का

बस संदेश भेज सकते हैं:

val inputMessage = Signal(FooInput, Foo) 
actor ! inputMessage 
1

यह अक्का के Akka's Typed Channel support की तरह लगता है इस को संबोधित किया था, लेकिन (the comment के अनुसार has already been removed from Akka in version 2.3)।

अक्का 2.2.3 के लिए प्रलेखन में, एक अच्छा "design background" अनुभाग जो समर्थन टाइप किए गए संदेश भेजता है और प्रतिक्रियाओं में कठिनाइयों पर चर्चा करता है।

वहाँ भी रोलाण्ड कुहन से एक अच्छा NEScala बात है, अक्का टाइप चैनल: मैक्रो ([YouTube]/[Slides]), आपके द्वारा लिखे गए चैनलों के कार्यान्वयन पर चर्चा करता है कि के रूप में लागू प्रकार गणना।

+1

टाइप किए गए चैनल पहले से ही [संस्करण 2.3 में अक्का से हटा दिए गए हैं] (http://doc.akka.io/docs/akka/snapshot/project/migration-guide-2.2.x-2.3.x.html) । "टाइप किए गए चैनल एक प्रयोगात्मक विशेषता थी जिसे हमने हटाने का निर्णय लिया: इसका कार्यान्वयन स्कैला की एक प्रयोगात्मक विशेषता पर निर्भर था जिसके लिए जावा और अन्य भाषाओं में कोई पत्राचार नहीं है और इसका उपयोग सहज नहीं था।" – dfan

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