Actually, again, this is very *un*common code -- all those statics are
awfully surprising.  Question: how much are you gluing Actors onto very
non-Actor code?  That's the only way I can interpret what you're doing
here, and it's a bit unusual in my experience -- Akka tends to be pretty
pervasive, so you don't generally see a *lot* of different types of Actors
being accessed from the outside.  More often, there's a *bit* of "Actor
API" exposed to the non-Akka code, and the rest is all Actors talking to
each other.  (Also, it's moderately unusual to be doing so much with
singleton Actors, especially with per-node singletons, so this pattern of
storing an ActorRef in a static, which only makes sense for a per-node
singleton, is downright rare in my experience.)

As for the isTerminated() check, that's automatically a bad smell -- the
isTerminated() method has been deprecated for a long, long time, and
doesn't even exist in current versions of Akka.  (I was downright puzzled
by it -- I'd never heard of it before, until I went Googling around.  Which
version of Akka are you using?)  I honestly don't know how that ever
worked: an ActorRef is really just a fancy sort of address itself (more
direct than ActorSelection, but still essentially an address), and has no a
priori knowledge of whether the Actor is still running or not.  From the
comments I'm finding online, isTerminated() apparently never worked very
well, and has been removed.

Instead, you usually pro-actively find out that an Actor has terminated by
putting a watcher (ActorContext.watch()) on it, so you get a notification
when it dies, and would typically null out the ActorRef  and maybe rebuild
the Actor at that point.  Honestly not sure how to do that watching from
outside the Actor world, though -- I've never tried something like that,
because like I said, it's not a common approach.  In your case, I probably
don't recommend trying.

Regardless, yes, there are potential race conditions.  That's pretty much
always an assumption in the Akka world: you assume that there are races,
and build the code to be tolerant of them as needed.  If the Actor has
died, then the messages will go to the dead letter box; in this case, the
caller should time out and react appropriately.

To your question of exceptions, no -- this doesn't look like it'll throw an
Exception per se.  Rather, the Exception (if there is one, usually a
timeout) is wrapped up in that Try you get back from value().  You're
checking the success case of that, but you should also handle the failure
case -- *that* is your signal that the Actor is dead.  (Or at least, that
it failed to return in time.)

Also, note that calling .value() is also automatically a bit of a bad smell
-- that's a blocking call, and blocking always leaves you in danger of
thread starvation and other such badness.  It may well be necessary, if the
surrounding code is all synchronous (common when adapting legacy systems),
but keep in mind that the more you can make stuff reactive and
Future-based, the less likely you are to get into trouble.

Finally, I caution about over-optimizing around assumptions of efficiency.
ActorSelection is a *bit* slower than ActorRef, yes, but my understanding
is that you're trying to do everything locally within the node anyway, so
my suspicion is that ActorSelection is still plenty fast.  So I *suspect*
you're complicating the code for what might be a very small optimization.
>From what I see here, I would *probably* just always use ActorSelection for
this code unless profiling indicated otherwise...

On Tue, Jun 7, 2016 at 11:48 AM, kraythe <[email protected]> wrote:

> I am currently adding Akka to our existing system that currently does
> distributed programming with Executors in Hazelcast. Obviously he executor
> system is not scaling so I am currently working on how to convert it to an
> actor system. The temptation I have is to do the code below for my scoring
> manager but it feels so boilerplate and common that I feel I must be
> missing something or doing something wrong. The scoring manager exists once
> per node and I need to call it from a lot of places including other actors
> so, upon reading the docs, I read that using ActorSelection to call all the
> time is a performance issue so I thought caching the ref would be a good
> idea. This is how I went about it.
>
> private static ActorRef scoringManagerRef = null;
>
> public static ActorRef start(final ActorSystem system) {
>     if (scoringManagerRef != null) throw new IllegalStateException("Already 
> started.");
>     scoringManagerRef = 
> system.actorOf(Props.create(LiveScoringManager.class));
>     return scoringManagerRef;
> }
>
> private static ActorSelection actorSelection(final ActorSystem system) {
>     return system.actorSelection(DEFAULT_PATH);
> }
>
> public static ActorRef actorRef() {
>     if (scoringManagerRef == null || scoringManagerRef.isTerminated()) {
>         scoringManagerRef = null;
>         final Option<Try<ActorRef>> value = 
> actorSelection(Ruckus.getActorSystem())
>                 .resolveOne(new Timeout(1, TimeUnit.SECONDS)).value();
>         if (value.isDefined()) scoringManagerRef = value.get().get();
>     }
>     return scoringManagerRef;
> }
>
>
> The idea is that since there is only one per node, we can start it when
> the ActorSystem goes up but if the actor system restarts the manager then
> we want to refresh the ref. Of course there is always the chance that
> milliseconds after we check for "isTerminated" the actor is actually
> terminated. I am not so sure what would happen then, messages to DLQ?
> Hopefully an exception would occur but which?
>
> Anyway I would need this pretty much everywhere on all of my Actors to
> make calling them efficient so this seems to be something I must be doing
> incorrectly. Any advice is appreciated.
>
>
> --
> >>>>>>>>>> Read the docs: http://akka.io/docs/
> >>>>>>>>>> Check the FAQ:
> http://doc.akka.io/docs/akka/current/additional/faq.html
> >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
> ---
> You received this message because you are subscribed to the Google Groups
> "Akka User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to