Merge pull request #24385 from jrudolph/jr/23697-start-receptionist-eagerly

=typ #23697 start typed receptionist eagerly
This commit is contained in:
Johannes Rudolph 2018-01-29 16:29:51 +01:00 committed by GitHub
commit 2fd4063d72
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 11 deletions

View file

@ -151,17 +151,32 @@ class ExtensionsSpec extends TypedAkkaSpec {
instance1 should be theSameInstanceAs instance2
}
"load registered typed extensions eagerly even for untyped system" in {
import akka.actor.typed.scaladsl.adapter._
val beforeCreation = InstanceCountingExtension.createCount.get()
val untypedSystem = akka.actor.ActorSystem()
try {
val before = InstanceCountingExtension.createCount.get()
InstanceCountingExtension(untypedSystem.toTyped)
val after = InstanceCountingExtension.createCount.get()
// should have been loaded even before it was accessed in the test because InstanceCountingExtension is listed
// as a typed library-extension in the config
before shouldEqual beforeCreation + 1
after shouldEqual before
} finally {
untypedSystem.terminate().futureValue
}
}
"not create an extension multiple times when using the ActorSystemAdapter" in {
import akka.actor.typed.scaladsl.adapter._
val untypedSystem = akka.actor.ActorSystem()
try {
val ext1 = DummyExtension1(untypedSystem.toTyped)
val ext2 = DummyExtension1(untypedSystem.toTyped)
val before = InstanceCountingExtension.createCount.get()
InstanceCountingExtension(untypedSystem.toTyped)
val ext = InstanceCountingExtension(untypedSystem.toTyped)
val after = InstanceCountingExtension.createCount.get()
(after - before) should ===(1)
ext1 should be theSameInstanceAs ext2
} finally {
untypedSystem.terminate().futureValue

View file

@ -14,8 +14,14 @@ akka.typed {
# Should not be set by end user applications in 'application.conf', use the extensions property for that
#
library-extensions = ${?akka.typed.library-extensions} []
# Receptionist is started eagerly to allow clustered receptionist to gather remote registrations early on.
library-extensions += "akka.actor.typed.receptionist.Receptionist"
}
# Load typed extensions by an untyped unextension.
akka.library-extensions += "akka.actor.typed.internal.adapter.ActorSystemAdapter$LoadTypedExtensions"
akka.actor {
serializers {
typed-misc = "akka.actor.typed.internal.MiscMessageSerializer"

View file

@ -14,7 +14,8 @@ import akka.serialization.{ BaseSerializer, SerializerWithStringManifest }
@InternalApi
class MiscMessageSerializer(val system: akka.actor.ExtendedActorSystem) extends SerializerWithStringManifest with BaseSerializer {
private val resolver = ActorRefResolver(system.toTyped)
// Serializers are initialized early on. `toTyped` might then try to initialize the untyped ActorSystemAdapter extension.
private lazy val resolver = ActorRefResolver(system.toTyped)
private val ActorRefManifest = "a"
def manifest(o: AnyRef): String = o match {

View file

@ -7,6 +7,8 @@ package adapter
import java.util.concurrent.CompletionStage
import akka.actor
import akka.actor.ExtendedActorSystem
import akka.actor.InvalidMessageException
import akka.{ actor a }
@ -29,8 +31,6 @@ import scala.compat.java8.FutureConverters
@InternalApi private[akka] class ActorSystemAdapter[-T](val untyped: a.ActorSystemImpl)
extends ActorSystem[T] with ActorRef[T] with internal.ActorRefImpl[T] with ExtensionsImpl {
loadExtensions()
import ActorRefAdapter.sendSystemMessage
// Members declared in akka.actor.typed.ActorRef
@ -96,11 +96,28 @@ private[akka] object ActorSystemAdapter {
object AdapterExtension extends a.ExtensionId[AdapterExtension] with a.ExtensionIdProvider {
override def get(system: a.ActorSystem): AdapterExtension = super.get(system)
override def lookup = AdapterExtension
override def lookup() = AdapterExtension
override def createExtension(system: a.ExtendedActorSystem): AdapterExtension =
new AdapterExtension(system)
}
/**
* An untyped extension to load configured typed extensions. It is loaded via
* akka.library-extensions. `loadExtensions` cannot be called from the AdapterExtension
* directly because the adapter is created too early during typed actor system creation.
*
* When on the classpath typed extensions will be loaded for untyped ActorSystems as well.
*/
class LoadTypedExtensions(system: a.ExtendedActorSystem) extends a.Extension {
ActorSystemAdapter.AdapterExtension(system).adapter.loadExtensions()
}
object LoadTypedExtensions extends a.ExtensionId[LoadTypedExtensions] with a.ExtensionIdProvider {
override def lookup(): actor.ExtensionId[_ <: actor.Extension] = this
override def createExtension(system: ExtendedActorSystem): LoadTypedExtensions =
new LoadTypedExtensions(system)
}
def toUntyped[U](sys: ActorSystem[_]): a.ActorSystem =
sys match {
case adapter: ActorSystemAdapter[_] adapter.untyped
@ -108,4 +125,3 @@ private[akka] object ActorSystemAdapter {
s"($sys of class ${sys.getClass.getName})")
}
}