Skip to content

Commit

Permalink
Extract "boot strap" settings into an ActorSystemSetting akka#21894
Browse files Browse the repository at this point in the history
  • Loading branch information
johanandren committed Dec 2, 2016
1 parent e525ec3 commit 68e9fff
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class ActorSystemSettingsSpec extends WordSpec with Matchers {
var system: ActorSystem = null
try {
val setting = DummySetting("Tad Moore")
system = ActorSystem("name", actorSystemSettings = ActorSystemSettings(setting))
system = ActorSystem("name", ActorSystemSettings(setting))

system.asInstanceOf[ExtendedActorSystem]
.actorSystemSettings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
package akka.serialization

import akka.actor.{ ActorSystem, ActorSystemSettings }
import akka.actor.{ ActorSystem, ActorSystemBootstrapSettings, ActorSystemSettings }
import akka.testkit.AkkaSpec
import com.typesafe.config.ConfigFactory

Expand All @@ -19,14 +19,7 @@ object SerializationSettingsSpec {
SerializerDetails("test", testSerializer, List(classOf[ProgrammaticDummy]))
)
}
val actorSystemSettings = ActorSystemSettings(serializationSettings)

}

class SerializationSettingsSpec extends AkkaSpec(
ActorSystem(
"SerializationSettingsSpec",
config = Some(ConfigFactory.parseString("""
val bootstrapSettings = ActorSystemBootstrapSettings(None, Some(ConfigFactory.parseString("""
akka {
actor {
serialize-messages = off
Expand All @@ -35,8 +28,13 @@ class SerializationSettingsSpec extends AkkaSpec(
}
}
}
""")),
actorSystemSettings = SerializationSettingsSpec.actorSystemSettings)
""")), None)
val actorSystemSettings = ActorSystemSettings(bootstrapSettings, serializationSettings)

}

class SerializationSettingsSpec extends AkkaSpec(
ActorSystem("SerializationSettingsSpec", SerializationSettingsSpec.actorSystemSettings)
) {

import SerializationSettingsSpec._
Expand Down
73 changes: 61 additions & 12 deletions akka-actor/src/main/scala/akka/actor/ActorSystem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,58 @@
package akka.actor

import java.io.Closeable
import java.util.concurrent.{ ConcurrentHashMap, ThreadFactory, CountDownLatch, RejectedExecutionException }
import java.util.concurrent.atomic.{ AtomicReference }
import java.util.concurrent.{ ConcurrentHashMap, CountDownLatch, RejectedExecutionException, ThreadFactory }
import java.util.concurrent.atomic.AtomicReference

import com.typesafe.config.{ Config, ConfigFactory }
import akka.event._
import akka.dispatch._
import akka.japi.Util.immutableSeq
import akka.actor.dungeon.ChildrenContainer
import akka.util._
import akka.util.Helpers.toRootLowerCase

import scala.annotation.tailrec
import scala.collection.immutable
import scala.concurrent.duration.{ Duration }
import scala.concurrent.{ Await, Future, Promise, ExecutionContext, ExecutionContextExecutor }
import scala.concurrent.duration.Duration
import scala.concurrent.{ Await, ExecutionContext, ExecutionContextExecutor, Future, Promise }
import scala.util.{ Failure, Success, Try }
import scala.util.control.{ NonFatal, ControlThrowable }
import java.util.Locale
import scala.util.control.{ ControlThrowable, NonFatal }
import java.util.Optional
import scala.compat.java8.OptionConverters._

object ActorSystemBootstrapSettings {

/**
* Scala API: Create bootstrap settings needed for starting the actor system
* @param classLoader If no ClassLoader is given, it obtains the current ClassLoader by first inspecting the current
* threads' getContextClassLoader, then tries to walk the stack to find the callers class loader, then
* falls back to the ClassLoader associated with the ActorSystem class.
* @param config Configuration to use for the actor system. If no Config is given, the default reference config will be obtained from the ClassLoader.
* @param defaultExecutionContext If defined the ExecutionContext will be used as the default executor inside this ActorSystem.
* If no ExecutionContext is given, the system will fallback to the executor configured under "akka.actor.default-dispatcher.default-executor.fallback".
*/
def apply(classLoader: Option[ClassLoader], config: Option[Config], defaultExecutionContext: Option[ExecutionContext]): ActorSystemBootstrapSettings =
new ActorSystemBootstrapSettings(classLoader, config, defaultExecutionContext)

/**
* Java API: Create bootstrap settings needed for starting the actor system
* @param classLoader If no ClassLoader is given, it obtains the current ClassLoader by first inspecting the current
* threads' getContextClassLoader, then tries to walk the stack to find the callers class loader, then
* falls back to the ClassLoader associated with the ActorSystem class.
* @param config Configuration to use for the actor system. If no Config is given, the default reference config will be obtained from the ClassLoader.
* @param defaultExecutionContext If defined the ExecutionContext will be used as the default executor inside this ActorSystem.
* If no ExecutionContext is given, the system will fallback to the executor configured under "akka.actor.default-dispatcher.default-executor.fallback".
*/
def create(classLoader: Optional[ClassLoader], config: Optional[Config], defaultExecutionContext: Optional[ExecutionContext]): ActorSystemBootstrapSettings =
apply(classLoader.asScala, config.asScala, defaultExecutionContext.asScala)

}

final class ActorSystemBootstrapSettings(
val classLoader: Option[ClassLoader],
val config: Option[Config],
val defaultExecutionContext: Option[ExecutionContext]) extends ActorSystemSetting

object ActorSystem {

Expand Down Expand Up @@ -56,6 +92,11 @@ object ActorSystem {
*/
def create(name: String): ActorSystem = apply(name)

/**
* Java API: Creates a new actor system with the specified name and settings
*/
def create(name: String, settings: ActorSystemSettings): ActorSystem = apply(name, settings)

/**
* Creates a new ActorSystem with the specified name, and the specified Config, then
* obtains the current ClassLoader by first inspecting the current threads' getContextClassLoader,
Expand Down Expand Up @@ -108,6 +149,18 @@ object ActorSystem {
*/
def apply(name: String): ActorSystem = apply(name, None, None, None)

/**
* Scala API: Creates a new actor system with the specified name and settings
*/
def apply(name: String, settings: ActorSystemSettings): ActorSystem = {
val bootstrapSettings = settings.get[ActorSystemBootstrapSettings]
val cl = bootstrapSettings.flatMap(_.classLoader).getOrElse(findClassLoader())
val appConfig = bootstrapSettings.flatMap(_.config).getOrElse(ConfigFactory.load(cl))
val defaultEC = bootstrapSettings.flatMap(_.defaultExecutionContext)

new ActorSystemImpl(name, appConfig, cl, defaultEC, None, settings).start()
}

/**
* Creates a new ActorSystem with the specified name, and the specified Config, then
* obtains the current ClassLoader by first inspecting the current threads' getContextClassLoader,
Expand Down Expand Up @@ -140,12 +193,8 @@ object ActorSystem {
name: String,
config: Option[Config] = None,
classLoader: Option[ClassLoader] = None,
defaultExecutionContext: Option[ExecutionContext] = None,
actorSystemSettings: ActorSystemSettings = ActorSystemSettings.empty): ActorSystem = {
val cl = classLoader.getOrElse(findClassLoader())
val appConfig = config.getOrElse(ConfigFactory.load(cl))
new ActorSystemImpl(name, appConfig, cl, defaultExecutionContext, None, actorSystemSettings).start()
}
defaultExecutionContext: Option[ExecutionContext] = None): ActorSystem =
apply(name, ActorSystemSettings(ActorSystemBootstrapSettings.apply(classLoader, config, defaultExecutionContext)))

/**
* Settings are the overall ActorSystem Settings which also provides a convenient access to the Config object.
Expand Down
6 changes: 5 additions & 1 deletion project/MiMa.scala
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,11 @@ object MiMa extends AutoPlugin {
ProblemFilters.exclude[MissingClassProblem]("akka.stream.stage.UpstreamDirective"),
ProblemFilters.exclude[MissingClassProblem]("akka.stream.stage.FreeDirective"),
ProblemFilters.exclude[MissingClassProblem]("akka.stream.stage.StatefulStage$AndThen"),
ProblemFilters.exclude[MissingClassProblem]("akka.stream.stage.SyncDirective")
ProblemFilters.exclude[MissingClassProblem]("akka.stream.stage.SyncDirective"),

// #21894 Programmatic configuration of the ActorSystem
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.actor.ActorSystemImpl.this"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.actor.ExtendedActorSystem.actorSystemSettings")
)
)
}
Expand Down

0 comments on commit 68e9fff

Please sign in to comment.