Reputation: 151
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
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
Reputation: 16859
You might want to look at Agents or the Futures and Agents chapter in general for this.
Upvotes: 1