2012-08-23 22 views
5

में async io से देर से उत्तर मैं कुछ समय के लिए अक्का का उपयोग कर रहा हूं। मैं async io के लिए देर से जवाब हल करने के लिए अपने कोड में कुछ पैटर्न देखना शुरू कर दिया। क्या यह कार्यान्वयन ठीक है? ब्लॉक के बिना देर से जवाब देने का एक और तरीका है?अक्का

class ApplicationApi(asyncIo : ActorRef) extends Actor { 
    // store senders to late reply 
    val waiting = Map[request, ActorRef]() 

    def receive = { 
     // an actore request for a user, store it to late reply and ask for asyncIo actor to do the real job 
     case request : GetUser => 
      waiting += (sender -> request) 
      asyncIo ! AsyncGet("http://app/user/" + request.userId) 
     // asyncio response, parse and reply 
     case response : AsyncResponse => 
      val user = parseUser(response.body) 
      waiting.remove(response.request) match { 
       case Some(actor) => actor ! GetUserResponse(user) 
      } 
    } 
} 

उत्तर

5

एक तरह से अवरुद्ध से बचने के लिए, जबकि एक जवाब का इंतजार कर ask विधि-a.k.a का उपयोग कर भेजने के लिए है। ? ऑपरेटर- जो Future देता है (! के विपरीत जो () देता है)।

onSuccess या foreach विधियों का उपयोग करके, आप उत्तर के साथ पूरा होने पर भविष्य में किए जाने वाले कार्यों को निर्दिष्ट कर सकते हैं। इस का उपयोग करने के लिए आप AskSupport विशेषता में मिश्रण की जरूरत है: क्योंकि प्रभाव क्या होगा बाहर के सिंक के साथ प्राप्त करते हैं,

class ApplicationApi(asyncIo : ActorRef) extends Actor with AskSupport { 

    def receive = { 
    case request: GetUser => 
     val replyTo = sender 
     asyncIo ? AsyncGet("http://app/user/" + request.userId) onSuccess { 
     case response: AsyncResponse => 
      val user = parseUser(response.body) 
      replyTo ! GetUserResponse(user) 
     } 

} 

बचें इस तकनीक का इस्तेमाल किसी भी पक्ष प्रभाव है कि ApplicationApi अभिनेता के राज्य को संशोधित करता है प्रदर्शन करने के लिए पाश। हालांकि, अन्य कलाकारों को संदेश अग्रेषित करना सुरक्षित होना चाहिए।


वैसे, यहाँ पैटर्न मैच के हिस्से के रूप वर्तमान sender कब्जा करने के लिए, एक चर करने के लिए इसे बाद में आवंटित करने के लिए जरूरत से परहेज एक चाल है।

trait FromSupport { this: Actor => 
    case object from { 
    def unapply(msg: Any) = Some(msg, sender) 
    } 
} 

class MyActor extends Actor with FromSupport { 
    def receive = { 
    case (request: GetUser) from sender => 
     // sender is now a variable (shadowing the method) that is safe to use in a closure 
    } 
} 
+1

मुझे लगता है कि आप सही हैं; मैं भूल गया कि 'प्रेषक' अभिनेता की एक परिवर्तनीय संपत्ति है और न केवल एक चर है जिसे बंद किया जा सकता है। –

+2

कि इंफिक्स निकालने वाला वास्तव में दिलचस्प है – sourcedelica

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