Do I need to use a separate ExecutionContext?

This is driving me slightly nuts. Inside an actor, I’m doing an HTTP call via Play’s WS library, which I understand to be asynchronous; and I’m combining that with some other asynchronous work in a Future. Since all of the work in the Future is asynchronous, do I need to pass a separate ExecutionContext to the PatternCS.pipe(…) call to avoid starving the actor messaging infrastructure?

// We must be careful not to close over any mutable actor state in this future.
CompletableFuture<PrivateProtocol> future = 
    accessTokenProvider.get(userKey, nrToken)
        .thenCompose(accessToken -> 
            permissionsGateway.byProjectId(host, accessToken, projectId, nrToken)
        .thenApply(permissions -> 
            UserPermissionsInProject.powerfull(userKey, projectId, permissions)
        .exceptionally(t -> new PrivateProtocol.RefreshFailure(projectId, t));

// Since the above future involves only non-blocking calls, I'm assuming that
// it's OK to use getContext().dispatcher() for the pipe.
PatternsCS.pipe(future, getContext().dispatcher()).to(getSelf(), replyTo);

That shouldn’t be needed? Do you see a starvation problem? If you add a println after pipe, do you see that output immediately?

Thanks very much for your response, Patrik. The code does work; it’s just that I want to avoid any potential problems as load increases. The permissionsGateway call can take up to two seconds; if that was blocking I/O, I know that the work should be done in a separate execution context; does that apply to asynchronous work too?

Since the client is async, it won’t keep the thread while waiting for a response from the HTTP server.

The dispatcher passed to PatternsCS.pipe is only needed for executing the send-to-actor logic when the CompletableFuture completes, so that won’t be expensive.

1 Like

Thanks very much, Johan. That’s the assurance that I have been seeking.