Caching of actor refs? Am I asking for trouble?

I’m using a Google Guava LoadingCache to provide child actors. Is that a bad idea? Will some kind of nasty threading issue bite me in the backside if I continue with this strategy?

Here’s the load method from my CacheLoader implementation:

    @Override
    public ActorRef<Foundation.Command> load(AccountId accountId) {
         ActorRef<Foundation.Command> actor = context.spawnAnonymous(
                Foundation.create(host, accountId, permissionFinder));
        context.watchWith(actor, RemoveFoundationActor.INSTANCE);
        return actor;
    }

Doing things with the internal state of an actor such as spawning children with context.spawn must only ever be done as a reaction to receiving a message, so a call to load on some thread that the CacheLoader maintains is not safe.

You’d have to replace that with triggering a request-response to the actor, that would then in turn be problematic because it’s not a synchronous operation, so you’d rather have a CompletionStage<ActorRef<Cmd>> - you’d need some form of async loading API in the cache.

Thanks @johanandren. I have decided to ditch my Guava LoadingCache, in favour of a LinkedHashMap that I can manage more explicitly. I don’t feel confident of understanding the LoadingCache's internal thread management.

Just FYI: you can use Caffeine instead of Guava’s LoadingCache. It allows you to define a loader which returns a CompletionStage. This way you can ask inside the loader and return the resulting CompletionStage; when it is complete, the cache will store the resulting actor ref. Caffeine has all the same additional tweaks as Guava’s cache does, and has some annoying bugs fixed.