akka-guide icon indicating copy to clipboard operation
akka-guide copied to clipboard

Prefer CoordinatedShutdown over system.whenTerminate

Open ignasi35 opened this issue 4 years ago • 4 comments

ScalikeJdbcSetup.init registers a termination callback:

  def init(system: ActorSystem[_]): Unit = {
    fromConfig(system.settings.config)
    system.whenTerminated.map { _ =>
      ConnectionPool.closeAll()
    }(scala.concurrent.ExecutionContext.Implicits.global)
  }

Instead, it could demonstrate how to register a Coordinated Shutdown task so users don't see multiple flavors of shutdown on the sample code. Also, it would be useful to introduce Coordinated Shutdown in the tutorial for users outgrowing the sample service and adding other libraries and features that require releasing resources.

ignasi35 avatar Feb 15 '21 18:02 ignasi35

I just realized the implementation is wrong. It is possible for a user to invoke ScalikeJdbcSetup.fromConfig and get the ScalikeJdbc backend initialized without having a termination callback registered.

We should probably make the fromConfig protected.

ignasi35 avatar Feb 15 '21 18:02 ignasi35

There is one risk of using CoordinatedShutdown. The resources would be destroyed before ordinary actors are stopped so the actors can't use them at the end.

In the example it's not a problem because entities and projections are stopped before the CoordinatedShutdown phase.

Might anyway be better to destroy after the ActorSystem. By the way, perhaps we should add another phase after system termination to CoordinatedShutdown so that it can be used in the same way as other phases instead of ActorSystem.whenTerminated.

patriknw avatar Feb 16 '21 11:02 patriknw

I'm not sure we need to make any improvements.

A user actor that relies on JDBC probably should be closed gracefully in a particular phase of coordinated shutdown and, if the users didn't register a shutdown task for that actor, then it means the actor can stop even if the connection pool is closed:

  1. If the user actor is processing requests, it's likely to be idle when coordinated shutdown reaches the last phase: the HTTP/gRPC ports should unbound and in-flight requests completed so it's safe to close the connection pool. In that case, it's probably irrelevant if the actor uses a shutdown task. If requests are cluster traffic, then we're on a similar situation: the user just needs to stop the actor after cluster leaving.
  2. If the user actor is processing data on the background in a loop., then it is useful (necessary?) that the user indicates what phase should the actor be shut down.

ignasi35 avatar Feb 22 '21 11:02 ignasi35

We're not in control of creating the JDBC connection. It's user code. So I think it's up to the user to manage the orderly shutdown.

ignasi35 avatar Feb 22 '21 11:02 ignasi35