Migrating akka cluster to typed

Hello

I have an akka cluster using cluster sharding with persistent actors, and I want to slowly migrate the cluster (and the persistent actors) to akka-typed (I’m using akka v 2.5.20).

I wanted to start with just migrating the persistent actors to typed before worrying about the sharding itself, but the akka-typed depency along with actor.provider="cluster" fails on runtime unless I provide the akka-cluster-typed dependency as well.

When I provide that dependency and try to deploy my changes to an environment with a running cluster, I get this error: Cluster Node [akka.tcp://xxx@100.120.195.42:2552] - Cluster validated this node config, but sent back incompatible settings: akka.cluster.typed.receptionist.distributed-key-count is missing

I’m using akka-management using kubernetesAPI for service discovery.

Is there any way for me to do this migration without doing a full cluster restart?

Cheers,
Oli

Hi Oli,

It would be good to know more about this, so we can fix the problem if any. You have the dependency akka-persistence-typed but not akka-cluster-typed and that throws some exception? Do you have a stack trace or logs?

This is a config check that both nodes have the same setting for this. You can work around this by disabling this check on the first rolling update, with config:

  akka.cluster.configuration-compatibility-check.checkers {
    receptionist = "akka.cluster.JoinConfigCompatCheckCluster"
  }

There should be a better way to disable a config check than defining another like I did above, but I don’t think that is currently possible. I created issue #26719 for that.

Then do another rolling update with the new version and remove the above config workaround.

Another thing you may ask is if it’s possible to do a rolling update of Untyped Sharding to Typed Sharding, with same entity types and keys. I have to look into that and created issue #26718 for that.

Hi Patrik

Just by introducing a dependency to akka-actor-typed v. 2.5.20 I get the following exception and stack trace:

Caused by: java.lang.RuntimeException: ClusterReceptionist could not be loaded dynamically. Make sure you have 'akka-cluster-typed' in the classpath.
	at akka.actor.typed.receptionist.ReceptionistImpl$$anonfun$1.applyOrElse(Receptionist.scala:46)
	at akka.actor.typed.receptionist.ReceptionistImpl$$anonfun$1.applyOrElse(Receptionist.scala:43)
	at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:38)
	at scala.util.Failure.recover(Try.scala:234)
	at akka.actor.typed.receptionist.ReceptionistImpl.<init>(Receptionist.scala:43)
	at akka.actor.typed.receptionist.Receptionist$.createExtension(Receptionist.scala:113)
	at akka.actor.typed.receptionist.Receptionist$.createExtension(Receptionist.scala:112)
	at akka.actor.typed.internal.ExtensionsImpl.$anonfun$createExtensionInstance$1(ExtensionsImpl.scala:89)
	at scala.Option.getOrElse(Option.scala:138)
	at akka.actor.typed.internal.ExtensionsImpl.createExtensionInstance(ExtensionsImpl.scala:89)
	at akka.actor.typed.internal.ExtensionsImpl.registerExtension(ExtensionsImpl.scala:78)
	at akka.actor.typed.internal.ExtensionsImpl.registerExtension$(ExtensionsImpl.scala:76)
	at akka.actor.typed.internal.adapter.ActorSystemAdapter.registerExtension(ActorSystemAdapter.scala:32)
	at akka.actor.typed.internal.ExtensionsImpl.$anonfun$loadExtensions$1(ExtensionsImpl.scala:45)
	at scala.collection.Iterator.foreach(Iterator.scala:941)
	at scala.collection.Iterator.foreach$(Iterator.scala:941)
	at scala.collection.AbstractIterator.foreach(Iterator.scala:1429)
	at scala.collection.IterableLike.foreach(IterableLike.scala:74)
	at scala.collection.IterableLike.foreach$(IterableLike.scala:73)
	at scala.collection.AbstractIterable.foreach(Iterable.scala:56)
	at akka.actor.typed.internal.ExtensionsImpl.loadExtensions$1(ExtensionsImpl.scala:39)
	at akka.actor.typed.internal.ExtensionsImpl.loadExtensions(ExtensionsImpl.scala:65)
	at akka.actor.typed.internal.ExtensionsImpl.loadExtensions$(ExtensionsImpl.scala:32)
	at akka.actor.typed.internal.adapter.ActorSystemAdapter.loadExtensions(ActorSystemAdapter.scala:32)
	at akka.actor.typed.internal.adapter.ActorSystemAdapter$LoadTypedExtensions.<init>(ActorSystemAdapter.scala:120)
	at akka.actor.typed.internal.adapter.ActorSystemAdapter$LoadTypedExtensions$.createExtension(ActorSystemAdapter.scala:126)
	at akka.actor.typed.internal.adapter.ActorSystemAdapter$LoadTypedExtensions$.createExtension(ActorSystemAdapter.scala:123)
	at akka.actor.ActorSystemImpl.registerExtension(ActorSystem.scala:962)
	at akka.actor.ActorSystemImpl.$anonfun$loadExtensions$1(ActorSystem.scala:995)
	at scala.collection.Iterator.foreach(Iterator.scala:941)
	at scala.collection.Iterator.foreach$(Iterator.scala:941)
	at scala.collection.AbstractIterator.foreach(Iterator.scala:1429)
	at scala.collection.IterableLike.foreach(IterableLike.scala:74)
	at scala.collection.IterableLike.foreach$(IterableLike.scala:73)
	at scala.collection.AbstractIterable.foreach(Iterable.scala:56)
	at akka.actor.ActorSystemImpl.loadExtensions$1(ActorSystem.scala:993)
	at akka.actor.ActorSystemImpl.loadExtensions(ActorSystem.scala:1007)
	at akka.actor.ActorSystemImpl.liftedTree2$1(ActorSystem.scala:882)
	at akka.actor.ActorSystemImpl._start$lzycompute(ActorSystem.scala:870)
	at akka.actor.ActorSystemImpl._start(ActorSystem.scala:870)
	at akka.actor.ActorSystemImpl.start(ActorSystem.scala:891)
	at akka.actor.ActorSystem$.apply(ActorSystem.scala:246)
	at akka.actor.ActorSystem$.apply(ActorSystem.scala:289)
	at akka.actor.ActorSystem$.apply(ActorSystem.scala:264)

That would be when you have akka-actor-typed and akka-cluster on the classpath, and use cluster as akka.actor.provider for the untyped cluster. Akka typed then detects that it is running in a cluster and wants to use a clustered receptionist. I’d argue this is what you’d expect to happen (services registered to the receptionist available from all nodes, typed group router routing over the cluster nodes etc), so just adding akka-cluster-typed is the solution. I don’t think there are any other consequences of adding the dependency unless you start actually using the typed cluster tools.

Thanks, I’d argue that we should harden that. Created issue #26750.