- ActorProcessor terminated eagerly when ConcatAll had just taken up a
new input stream but not yet received onSubscribe for it
- The ActorProcessor eagerly shuts itself down upon onError and that
cannot be changed without completely reworking the Pump, so I opted
for just tracking the outstanding substreamSubscribers that have not
yet seen OnSubscribe and making them cancel properly when that arrives
(possibly later).
The problem was reproduced with the TCK PrefixAndTailTest
required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber
The tck subscriber was still referenced. Profiling revealed that the
root cause was the VirtualPublisher that holds a reference to the
realPublisher, which was MultiStreamOutputProcessor$SubstreamOutput,
which had the reference to the subscriber. The VirtualPublisher
is created by the Sink.publisher in the test, and the test holds
on to that VirtualPublisher reference.
The solution is to null out realPublisher field in the VirtualPublisher.
The old workaround with the NullSubscriber was removed.
Also made Sink.publisher reject additional subscribers.
Changed rules:
* 1.9 Always onSubscribe prior to any other signals
* 1.9 NullPointerException if subscriber is null
* 3.17 Long overflow, effectively unbounded instead of onError
Fixed some more things:
* fixed some FIXME
* Long drop and take
* memory leaks in tck tests, use BeforeClass to create ActorSystem
use AfterClass to shutdown ActorSystem
* more tck tests
* don't emit OnComplete when substream is cancelled
* work around for memory leak in PrefixAndTail
* FlowMaterializer is now the actor independent interface
* ActorFlowMaterializer is the actor based interface
* MaterializerSettings renamed to ActorFlowMaterializerSettings
* impl.ActorBasedFlowMaterializer renamed to impl.ActorFlowMaterializerImpl
* Optimizations included in ActorFlowMaterializerSettings
* Note that http is using FlowMaterializer in api, but I suspect that it
will currently only run with a ActorFlowMaterializer
Only failing test is for the SynchronousIterablePublisher since the TCK doesn't handle sync
publishers well (@ktoso is working to fix this for the 1.0.0.RC1)
Adds a lot of FIXMEs to make sure we fix them before we ship the final version of Akka Streams.
Additional fix for race when timout put to mailbox, then timeout cancelled and subscribe succeeds.
So it could happen, that JUST BEFORE `subscriptionTimeout.cancel()` the
`SubstreamSubscriptionTimeout` was already put into the actor's mailbox,
the cancelling then kicks in (does nothing) and then the attaching of
the subscriber kicks in, it passes OK. So the actor gets the timeout
first and then the subscription... So the publisher is already
subscribed to by some subsciber. But now the actor gets the
SubstreamSubscriptionTimeout message, and wants to subscribe the
cancelling subscriber to it. The publisher can only handle 1 subscriber,
so attaching of the cancelling subscriber will fail - well this is not
very bad, because it will just onError the cancelling subscriber rigth
away, but it can be missleading because the debug log will contain the
"cancelling... after..." message, while it has not REALLY cancelled it.
The isAttached can not be added to handleSubscriptionTimeout because
there it's "too late" and the log message would already be sent..
So while writing this up I noticed that it's not an "error race", but
it's still a race we could avoid when putting this isAttached check
before cancelling the publisher... do you think it's worth it?
The completeSubstreamOutput is used to not early complete the stream,
where as invalidating would shutdown the stream too early (and elements
wouldn't be emitted as expected).
* had to change api because of trait+object not useable from java
* ActorSubscriber.RequestStrategy and its implementations moved to
top level
* messages moved to ActorSubscriberMessage and ActorPublisherMessage
object