Thank you, Jenkins and CallingThreadDispatcher, for without you both I
would probably not have found this bug before the milestone release. So,
what happened? Well, ActorModelSpec for the CallingThreadDispatcher
tries to have an actor kill itself twice with InterruptedException (of
all things!) and wants to verify that everything still works. Given the
right timing (which was rare) the semantics of the
CallingThreadDispatcher would mean that the actor would suspend itself
(first failure), inform its supervisor (“/user”, not on CTD) and return
to the spec. If the supervisor was too slow to finish the restart which
includes a resume which will process all messages enqueued meanwhile
from the test BEFORE the test enqueued the second failure, the failure
would actually happen on the supervisor’s thread. Now
InterruptedException is the ONLY exception which always gets passed up,
and thus it is the only Exception which can ever occur genuinely within
a top-level supervisor which will trigger its restart: if it’s an
unhandled one, the actor system will stop, and if it’s a handled one
from a child there will be no problem.
So, having these very special circumstances combined just so, the
“guardian” would restart, and after today’s changes that meant killing
all its children. Boom.
The fix is of course trivial, as always. And the bug is extremely
obvious, once found. Cost me five hours.
- no config files used by microkernel
- boot classes are specified as main arguments
- actor system creation is left to user in Bootable
- added on-out-of-memory handler to java args
- updated docs
- handleChildTerminated/handleFailure: no discussion
- currentMessage was (ab)used by IO, fixed by down-casting which IO
already does for writing to currentMessage (ewww)
- Actor.apply() could now as well be moved to ActorCell, leaving Actor
as user-API-only, which would be nice but not for M1
- this is why I don’t really like lazy vals: not used during the whole
application life, only to be started after everything else is
shut-down, then complaining that the scheduler is gone
- better start it explicitly in .start(), where it can as well be a
volatile field
Added docs (Scala and Java) and (code for the docs) for 'Props'.
Renamed UntypedActorTestBase to UntypedActorDocTestBase.
Signed-off-by: Jonas Bonér <jonas@jonasboner.com>