Spring Service invocation goes to seperate thread

Hi All,

In my application I have Akka and Spring integrated i.e. I can call Spring Boot services from an actor.
Integration is based on Akka Extensions.
Spring service in injected into the actor by means of @Autowired annotation.
When I call Spring service inside the actor everything works just fine but I noticed that Spring service is executed within a different thread than the thread that was used by default dispatcher to invoke an actor.

For some reason I would like to have Spring service to be invoked with the same thread as the “owning” actor is.

So my question is why does Akka use different thread to execute Spring service and what could be done for workaround?

Thanks
Lukasz

Can you provide more details? How are you calling the Spring service from the actor? Is it just a normal method call? If so, that should execute on the same thread as the calling actor. How are you checking the threads?

I might be misunderstanding what you mean, but it’s normal for an actor to process a message on a different thread than the sender of the message, so perhaps that’s what you’re seeing?

Hi Tim,

Please find below answers to your questions.

  1. I’m calling the Spring service directly from the actor code, just like that: myService.findScenarioByIncomingNumber(incomingNumber);
  2. The Spring service is injected into actor code via @Autowired annotation.
  3. I check execution threads using logs:

2019-12-11 12:35:00.694 DEBUG [vpabx-akka-spring-akka.actor.default-dispatcher-4] [87115076112513_MT] [] p.o.v.c.a.MyActor.$anonfun$applyOrElse$4 Current step:yyyy.yyyyy.yyyyy.StepStartDtoImpl@79e99d7e
2019-12-11 12:35:00.703 DEBUG [vpabx-akka-spring-akka.actor.default-dispatcher-3]
[87115076112513_MT] [] p.o.v.d.s.MyServiceImpl.findScenarioByIncomingNumber;

  1. The event is received and is processed within MyActor and as part of this processing Spring managed service is invoked in the way presented above -> 1 point.

  2. Spring is integrated with the Akka using Akka extensions. I followed this guide: https://www.baeldung.com/akka-with-spring

Thanks.

There’s no way an ordinary synchronous method call can execute on a different thread than the caller, so there must be some missing piece. Can you post the code that you’re running?

I can think of two possible explanations:

  1. If the execution of myService.findScenarioByIncomingNumber(incomingNumber) isn’t actually in the main message receiver of the actor, but is actually called from some callback that is itself executed on another thread (for example, if it’s in a callback on a Future).
  2. The Spring service itself could be using something like Spring’s async support to intercept the method call and run the underlying service asynchronously.

Also, it might be a good idea to re-evaluate whether your really need it to execute on the same thread. Reliance on thread locals is discouraged in Akka applications (or any reactive design), and generally makes things harder to reason about. If you can pass context explicitly, or using a Scala implicit parameter, that might be a more robust option than trying to ensure that the thread is the same.

Hi Tim,

First, Thanks for your help.
Tomorrow at the latest I will provide you with all necessary information.

Tim,

Invocation chain goes like that: actor --> SpringService —> DAOObject

I’m posting some code:

The Actor:

@Component
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MyServiceActor extends AbstractActor {

@Autowired
private ScenarioService scenarioService;

}

@Service
public class ScenarioServiceImpl implements ScenarioService {

@Autowired
private ScenarioDao scenarioDao;
}

And as I mentioned before the ScenarioService object is executed in the different thread:

2019-12-11 12:35:00.703 DEBUG [ vpabx-akka-spring-akka.actor.default-dispatcher-3 ]
[87115076112513_MT] [] p.o.v.d.s.MyServiceImpl.findScenarioByIncomingNumber;

And one more thing - I’m checking some aspects of async support.

Thanks