* When Watch is sent to deadLetters it will generate Terminated
* Test: receive Terminated when watched node is unknown host
* Test: receive Terminated when watched path doesn't exist
- it was always intended that tell() (and sendSystemMessage()) shall not
throw any exceptions
- this is implemented by swallowing in ActorCell
(suspend/resume/restart/stop/!/sendSystemMessage) and in
RemoteActorRef (!/sendSystemMessage)
- current implementation uses a normal method, which adds overhead but
keeps the code in one place (ActorCell.catchingSend); this is a great
opportunity for making use of macros
This has brought to light some interesting effects (aka bugs) both in
the general implementation as well as in previous fixes.
SupervisorHierarchySpec is without TODOs now and GREEN.
- always suspend/resume for Suspend/Resume/Recreate, no matter which
state the actor is in, to keep the counter balanced
- preRestart failures are logged but otherwise ignored; there’s nothing
else (apart from terminating the actor) which we could do at that
point
- preRestart/postRestart exceptions have their own distinguishable
subtype of ActorKilledException now
- fix some race conditions in tests to make them produce fewer false
failures
- remove cruft from SupervisorStrategy and add methods which can
actually be used to implement your own (with proper warning signs)
- introducing RepointableActorRef, which starts out with an
UnstartedActorCell which can cheaply be created; the Supervise()
message will trigger child.activate() in the supervisor, which means
that the actual creation (now with normal ActorCell) happens exactly
in the right place and with the right semantics. Messages which were
enqueued to the dummy cell are transferred atomically into the
ActorCell (using normal .tell()), so message sends keep working
exactly as they used to
- this enables getting rid of the brittle synchronization around
RoutedActorRef by replacing that one with a RepointableActorRef
subclass which creates RoutedActorCells upon activate(), with the nice
benefit that there is no hurry then to get it right because the new
cell is constructed “on the side”
misc fixes:
- InvalidMessageException is now actually enforced when trying to send
“null”
- Mailboxes may be created without having an ActorCell, which can come
in handy later, because the cell is only needed when this mailbox is
going to be scheduled on some executor
- remove occurrences of Props(), which is equivalent to Props[Nothing],
which is equivalent to «bug»
- add test case which verifies that context.actorOf is still synchronous
- plus all the stuff I have forgotten.
- replace TreeMap with custom ChildrenContainer, which has three
implementations: empty, normal and “terminating” (i.e. waiting for
some child to terminate)
- split recreate() in the same way as terminate(), so that there is a
phase during which the suspended actor waits for termination of all
children which were stopped in preRestart
- do not null out “actor” in ActorCell during restart, because we do
need the supervisionStrategy and nulling it out does not buy us much
in this case anyway
- provide new ActorContext.suspendForChildTermination(), which enters
limbo for as long there are outstanding termination requests; this
enables code which is very similar to previously (half-working) setups
with “synchronous” context.stop(child)
docs are still missing, plus a little polishing here and there; oh, and
before I forget: ActorCell NOW is 64 bytes again ;-)
- PropertyMaster is the only place in Akka which calls
ClassLoader.getClass (apart from kernel, which might be special)
- all PropertyMaster methods (there are only three) take a ClassManifest
of what is to be constructed, and they verify that the obtained object
is actually compatible with the required type
Other stuff:
- noticed that I had forgotten to change to ExtendedActorSystem when
constructing Extensions by ExtensionKey (damn you, reflection!)
- moved Serializer.currentSystem into JavaSerializer, because that’s the
only one needing it (it’s only used in readResolve() methods)
- Serializers are constructed now with one-arg constructor taking
ExtendedActorSystem (if that exists, otherwise no-arg as before), to
allow JavaSerializer to do its magic; possibly necessary for others as
well
- Removed all Option[ClassLoader] signatures
- made it so that the ActorSystem will try context class loader, then
the class loader which loaded the class actually calling into
ActorSystem.apply, then the loader which loaded ActorSystemImpl
- for the second of the above I added a (reflectively accessed hopefully
safe) facility for getting caller Class[_] objects by using
sun.reflect.Reflection; this is optional an defaults to None, e.g. on
Android, which means that getting the caller’s classloader is done on
a best effort basis (there’s nothing we can do because a StackTrace
does not contain actual Class[_] objects).
- refactored DurableMailbox to contain the owner val and use that
instead of declaring that in all subclasses
- add Deploy to Props, which is used as the basis (overridden by
configuration)
- utilize general mechanism .withFallback (introduced on Deploy,
RouterConfig and Scope)
- actually pass Props over the wire when deploying remotely in order to
retain settings (this was an oversight before)
- write tests for the new functionality
- re-label Client/Server to Inbound/Outbound for netty settings
description
- move to just using exactly one class loader for all reflective
activities of the ActorSystem, which is either the context class
loader or the one which loaded the ActorSystem’s class; document that
putting Akka on boot class path will not work
- be more careful with initializing the Client- and ServerBootstrap
- rename Port to DesiredPortFromConfig to discourage misuse
- write test for NettySettings
- various small fixes
- move all creation of ActorRefs into the ActorRefProvider (deadLetters,
locker)
- rootPath does not contain remote transport address any longer in order
to start the LocalActorRefProvider before the RemoteTransport; the
transport address is inserted during serialization only, which enables
us later to have more than one transport available for one actor
system (maybe even needed for clustering)
- fix inheritance between DeadLetterActorRef and EmptyLocalActorRef
- document some start-up dependencies by reordering constructor code
- fix remote tests which used self.path for identifying remote actors
(since that no longer includes the remote transport address)