Stephen Woods
Stephen Woods

Reputation: 151

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:

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)?

Upvotes: 0

Views: 796

Answers (2)

Derrops
Derrops

Reputation: 8107

I'm not sure exactly what your asking by non-actor world, do you mean ask?

ActorSystem system = ActorSystem.create("system");
ActorRef actor = system.actorOf(Props.create(SomeActor.class), "someActor");

Timeout t = new Timeout(5, TimeUnit.SECONDS);
Future<Object> future = Patterns.ask(actor, "some message", 1000);
try {String response = (String) Await.result(future, t.duration());} catch(Exception e){}

So basically you send message being "some message" to the SomeActor actor, then in it's onReceive method you need to have

    public void onReceive(Object msg) throws Exception
    {
            if (msg instancof String)
            {
                getSender().tell("here is the response");
            }
    }

so if you do a System.out.println(response) it will print "here is the response" But yeah could use agents as well as shown in the comments but they freak me out ( ;

Upvotes: 0

agilesteel
agilesteel

Reputation: 16859

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

Upvotes: 1

Related Questions