improve safety of Props.create by allowing Creator<T>, see #3377

Props constructors need to be deprecated instead of being mutated
because we cannot just start throwing exceptions in people’s existing
code. Props.withCreator is deprecated for similar reasons, but also
because Props are about the creators, so replacing that after the fact
is not good style.
This commit is contained in:
Roland 2013-05-28 10:39:38 +02:00
parent 58756be937
commit f8fa825e48
11 changed files with 222 additions and 45 deletions

View file

@ -85,18 +85,21 @@ for a migration period):
.. includecode:: code/docs/actor/ActorDocSpec.scala#creating-props-deprecated
The last one is deprecated because its functionality is available in full
through :meth:`Props.apply()`.
The first one is deprecated because the case class structure changed between
Akka 2.1 and 2.2.
The first three are deprecated because the captured closure is a local class
which means that it implicitly carries a reference to the enclosing class. This
can easily make the resulting :class:`Props` non-serializable, e.g. when the
enclosing class is an :class:`Actor`. Akka advocates location transparency,
meaning that an application written with actors should just work when it is
deployed over multiple network nodes, and non-serializable actor factories
would break this principle. In case indirect actor creation is needed—for
example when using dependency injection—there is the possibility to use an
:class:`IndirectActorProducer` as described below.
The two variants in the middle are deprecated because :class:`Props` are
primarily concerned with actor creation and thus the “creator” part should be
explicitly set when creating an instance. In case you want to deploy one actor
in the same was as another, simply use
``Props(...).withDeploy(otherProps.deploy)``.
The last one is not technically deprecated, but it is not recommended because
it encourages to close over the enclosing scope, resulting in non-serializable
:class:`Props` and possibly race conditions (breaking the actor encapsulation).
We will provide a macro-based solution in a future release which allows similar
syntax without the headaches, at which point this variant will be properly
deprecated.
There were two use-cases for these methods: passing constructor arguments to
the actor—which is solved by the newly introduced

View file

@ -243,19 +243,19 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) {
//#creating-props
//#creating-props-deprecated
// DEPRECATED: encourages to close over enclosing class
// DEPRECATED: old case class signature
val props4 = Props(
creator = { () new MyActor },
dispatcher = "my-dispatcher")
// DEPRECATED: encourages to close over enclosing class
// DEPRECATED due to duplicate functionality with Props.apply()
val props5 = props1.withCreator(new MyActor)
// DEPRECATED: encourages to close over enclosing class
val props6 = Props(new MyActor)
// DEPRECATED due to duplicate functionality with Props.apply()
val props7 = props1.withCreator(classOf[MyActor])
val props6 = props1.withCreator(classOf[MyActor])
// NOT RECOMMENDED: encourages to close over enclosing class
val props7 = Props(new MyActor)
//#creating-props-deprecated
}