Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe for Akka actor become method to close over immutable state?

Tags:

scala

akka

actor

The purpose here is to implement a very simple cache for an actor that needs to call an external service (or some expensive but highly cacheable operation) without using mutable state.

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
  }
}

I know there are more advanced ways to implement this, among which a fully fledged CacheSystem that can be found in the Akka patterns pages, but in some cases that really isn't required.

Plus, it's interesting to know the answer if using become like this is safe.

like image 573
Cristian Vrabie Avatar asked Sep 30 '13 18:09

Cristian Vrabie


People also ask

Are akka actors thread safe?

Actors are 'Treadsafe'. The Actor System (AKKA), provides each actor with its own 'light-weight thread'. Meaning that this is not a tread, but the AKKA system will give the impression that an Actor is always running in it's own thread to the developer.

Is akka event driven?

Akka is an open source, event-driven middleware project. It is designed to allow developers to write simpler, correct concurrent applications using Actors, STM and transactors. Akka is an open source, event-driven middleware project.

Is akka ask blocking?

No, using the ? does not block the current thread. It returns a Future immediately.

How does akka persistence work?

Akka Persistence enables stateful actors to persist their state so that it can be recovered when an actor is either restarted, such as after a JVM crash, by a supervisor or a manual stop-start, or migrated within a cluster.


1 Answers

As far as I know this technique is sound and should be good for you to use. It's actually a more clever way to get around having to have a mutable var response in your code. I actully used this technique in an answer here and Viktor from the Akka team seemed to think it was a good solution. One thing though, you can change:

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

to:

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

The Receive type is a shorthand alias for PartialFunction[Any,Unit].

like image 103
cmbaxter Avatar answered Oct 19 '22 14:10

cmbaxter