Search code examples
javaakkaactor

How do I expose the immutable messages of an Akka Actor to non-actor world?


I'm struggling with the interaction of actor systems and non-actor code. Section 3.2.1 of the Akka Java documentation describes using TypedActors to perform bridging between an Actor system and the outside non-actor world.

Typed actors are nice for bridging between actor systems (the “inside”) and non-actor code (the “outside”), because they allow you to write normal OO-looking code on the outside.

It then goes on to describe three different scenarios:

  • One-way message send
  • Request-reply message send
  • Request-reply-with-future message send

But all of those scenarios are initiated from the non-actor world. What is the proper way for the actor system to call the non-actor code?

What I'm trying to do is expose the immutable payload of an actor message directly to the non-actor world. For example, actor A retains the immutable payload (say a map) of a message that it receives from actor B as a volatile instance variable, and then exposes that variable to the non-actor world for performance reasons (via a normal getter or a facade). That map is immutable, so its inherently thread-safe and thus does not require the overhead of routing messages, etc. Actor A is accessed by lots of non-actor threads and every once in a while, it receives an updated map from Actor B.

public class ActorAFacade extends UntypedActor implements Map<String, String> {
    private volatile Map<String, String> immutableMap = Collections.emptyMap();

    @Override
    public String get(Object key) {
       return immutableMap.get(key);
    }

    @Override
    public String put(String key, String value) {
        throw new UnsupportedOperationException("Read Only!");
    }

    ... 

    @Override
    public void onReceive(Object message) throws Exception {
        if (message instanceof Map) {            
            immutableMap = (Map<String, String>) message;
        } else {
            unhandled(message);
        }
    }
}

I would like to avoid the overhead of creating and routing messages for each of the map methods (whether its done manually by an untyped actor or automatically by a typed actor).

Is this hybrid approach a viable solution (does it violate the spirit of actor systems)? Is there a better approach that Akka provides (i.e an event bus, call backs, etc)?


Solution

  • You might want to look at Agents or the Futures and Agents chapter in general for this.