2013-09-30 3 views
10

Lo scopo qui è di implementare una cache molto semplice per un attore che deve chiamare un servizio esterno (o un'operazione costosa ma altamente memorizzabile nella cache) senza utilizzare lo stato mutabile.È sicuro che l'attore Akka diventi un metodo per chiudere lo stato immutabile?

class A extends Actor{ 
    def receive = { 
    case GetCommand => 
     val response = callExternalService() 
     context.become(receiveWithCache(response)) 
     context.system.scheduler.schedule(1 day, 1 day, self, InvalidateCache) 
     sender ! response 
    } 
    def receiveWithCache(cachedResponse:R): PartialFunction[Any,Unit] = { 
    case GetCommand => sender ! cachedResponse 
    case InvalidateCache => context.unbecome 
    } 
} 

So che ci sono modi più avanzati per attuare questo, tra i quali un CacheSystem a tutti gli effetti che si possono trovare nelle pagine modelli Akka, ma in alcuni casi che in realtà non è necessaria.

Inoltre, è interessante conoscere la risposta se l'utilizzo diventa così sicuro.

+0

Non vedo l'ora di rispondere da solo perché questo è abbastanza elegante. – yan

+0

Perché non chiudere in sicurezza lo stato immutabile? –

+0

1) Non penso che evitare lo stato (locale) a tutti i costi sia ragionevole - per favore mi illumini se mi manca qualcosa - e 2) non sembrerebbe più bello usare una funzione anonima (parziale) con 'context. diventare 'invece di un metodo? –

risposta

12

Per quanto ne so questa tecnica è valida e dovrebbe essere utile per l'utente. In realtà è un modo più intelligente per aggirare il fatto di dover avere un codice mutabile var response nel codice. Ho usato prontamente questa tecnica in una risposta here e Viktor della squadra di Akka sembrava pensare che fosse una buona soluzione. Una cosa, però, è possibile cambiare:

def receiveWithCache(cachedResponse:R): PartialFunction[Any,Unit] = { 
    case GetCommand => sender ! cachedResponse 
    case InvalidateCache => context.unbecome 
} 

a:

def receiveWithCache(cachedResponse:R): Receive = { 
    case GetCommand => sender ! cachedResponse 
    case InvalidateCache => context.unbecome 
} 

Il tipo Receive è un alias scorciatoia per PartialFunction[Any,Unit].

+5

È anche il modo consigliato per farlo. Espandere la domanda: 'diventare' non lascia il contesto dell'attore, quindi è completamente sicuro, anche per lo stato mutabile. –