=str fix sub-upstream cancellation in concatAll

- 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).
This commit is contained in:
Roland Kuhn 2015-06-18 22:24:24 +02:00
parent 6e72271eb5
commit d462cdd1b4
16 changed files with 115 additions and 45 deletions

View file

@ -348,7 +348,7 @@ class LowLevelOutgoingConnectionSpec extends AkkaSpec("akka.loggers = []\n akka.
}
class TestSetup {
val requests = TestPublisher.manualProbe[HttpRequest]
val requests = TestPublisher.manualProbe[HttpRequest]()
val responses = TestSubscriber.manualProbe[HttpResponse]
val remoteAddress = new InetSocketAddress("example.com", 80)
@ -357,7 +357,7 @@ class LowLevelOutgoingConnectionSpec extends AkkaSpec("akka.loggers = []\n akka.
val (netOut, netIn) = {
val netOut = TestSubscriber.manualProbe[ByteString]
val netIn = TestPublisher.manualProbe[ByteString]
val netIn = TestPublisher.manualProbe[ByteString]()
FlowGraph.closed(OutgoingConnectionBlueprint(remoteAddress, settings, NoLogging)) { implicit b
client

View file

@ -406,7 +406,7 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|Host: example.com
|
|""".stripMarginWithNewline("\r\n"))
val data = TestPublisher.manualProbe[ByteString]
val data = TestPublisher.manualProbe[ByteString]()
inside(expectRequest) {
case HttpRequest(GET, _, _, _, _)
responsesSub.sendNext(HttpResponse(entity = HttpEntity.Default(ContentTypes.`text/plain`, 4, Source(data))))
@ -429,7 +429,7 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|Host: example.com
|
|""".stripMarginWithNewline("\r\n"))
val data = TestPublisher.manualProbe[ByteString]
val data = TestPublisher.manualProbe[ByteString]()
inside(expectRequest) {
case HttpRequest(GET, _, _, _, _)
responsesSub.sendNext(HttpResponse(entity = HttpEntity.CloseDelimited(ContentTypes.`text/plain`, Source(data))))
@ -453,7 +453,7 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|Host: example.com
|
|""".stripMarginWithNewline("\r\n"))
val data = TestPublisher.manualProbe[ChunkStreamPart]
val data = TestPublisher.manualProbe[ChunkStreamPart]()
inside(expectRequest) {
case HttpRequest(GET, _, _, _, _)
responsesSub.sendNext(HttpResponse(entity = HttpEntity.Chunked(ContentTypes.`text/plain`, Source(data))))
@ -477,7 +477,7 @@ class HttpServerSpec extends AkkaSpec("akka.loggers = []\n akka.loglevel = OFF")
|Connection: close
|
|""".stripMarginWithNewline("\r\n"))
val data = TestPublisher.manualProbe[ByteString]
val data = TestPublisher.manualProbe[ByteString]()
inside(expectRequest) {
case HttpRequest(GET, _, _, _, _)
responsesSub.sendNext(HttpResponse(entity = CloseDelimited(ContentTypes.`text/plain`, Source(data))))

View file

@ -29,13 +29,13 @@ abstract class HttpServerTestSetupBase {
implicit def materializer: FlowMaterializer
val requests = TestSubscriber.manualProbe[HttpRequest]
val responses = TestPublisher.manualProbe[HttpResponse]
val responses = TestPublisher.manualProbe[HttpResponse]()
def settings = ServerSettings(system).copy(serverHeader = Some(Server(List(ProductVersion("akka-http", "test")))))
def remoteAddress: Option[InetSocketAddress] = None
val (netIn, netOut) = {
val netIn = TestPublisher.manualProbe[ByteString]
val netIn = TestPublisher.manualProbe[ByteString]()
val netOut = TestSubscriber.manualProbe[ByteString]
FlowGraph.closed(HttpServerBluePrint(settings, remoteAddress = remoteAddress, log = NoLogging)) { implicit b

View file

@ -222,7 +222,7 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
"for a strict message larger than configured maximum frame size" in pending
"for a streamed message" in new ServerTestSetup {
val data = ByteString("abcdefg", "ASCII")
val pub = TestPublisher.manualProbe[ByteString]
val pub = TestPublisher.manualProbe[ByteString]()
val msg = BinaryMessage.Streamed(Source(pub))
netOutSub.request(6)
pushMessage(msg)
@ -245,7 +245,7 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
"for a streamed message with a chunk being larger than configured maximum frame size" in pending
"and mask input on the client side" in new ClientTestSetup {
val data = ByteString("abcdefg", "ASCII")
val pub = TestPublisher.manualProbe[ByteString]
val pub = TestPublisher.manualProbe[ByteString]()
val msg = BinaryMessage.Streamed(Source(pub))
netOutSub.request(7)
pushMessage(msg)
@ -278,7 +278,7 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
"for a strict message larger than configured maximum frame size" in pending
"for a streamed message" in new ServerTestSetup {
val text = "äbcd€fg"
val pub = TestPublisher.manualProbe[String]
val pub = TestPublisher.manualProbe[String]()
val msg = TextMessage.Streamed(Source(pub))
netOutSub.request(6)
pushMessage(msg)
@ -310,7 +310,7 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
println(half1(0).toInt.toHexString)
println(half2(0).toInt.toHexString)
val pub = TestPublisher.manualProbe[String]
val pub = TestPublisher.manualProbe[String]()
val msg = TextMessage.Streamed(Source(pub))
netOutSub.request(6)
@ -327,7 +327,7 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
"for a streamed message with a chunk being larger than configured maximum frame size" in pending
"and mask input on the client side" in new ClientTestSetup {
val text = "abcdefg"
val pub = TestPublisher.manualProbe[String]
val pub = TestPublisher.manualProbe[String]()
val msg = TextMessage.Streamed(Source(pub))
netOutSub.request(5)
pushMessage(msg)
@ -382,7 +382,7 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
s.request(2)
sub.expectNext(ByteString("123", "ASCII"))
val outPub = TestPublisher.manualProbe[ByteString]
val outPub = TestPublisher.manualProbe[ByteString]()
val msg = BinaryMessage.Streamed(Source(outPub))
netOutSub.request(10)
pushMessage(msg)
@ -459,7 +459,7 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
messageIn.expectComplete()
// sending another message is allowed before closing (inherently racy)
val pub = TestPublisher.manualProbe[ByteString]
val pub = TestPublisher.manualProbe[ByteString]()
val msg = BinaryMessage.Streamed(Source(pub))
pushMessage(msg)
expectFrameOnNetwork(Opcode.Binary, ByteString.empty, fin = false)
@ -504,7 +504,7 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
// sending another message is allowed before closing (inherently racy)
val pub = TestPublisher.manualProbe[ByteString]
val pub = TestPublisher.manualProbe[ByteString]()
val msg = BinaryMessage.Streamed(Source(pub))
pushMessage(msg)
expectFrameOnNetwork(Opcode.Binary, ByteString.empty, fin = false)
@ -549,7 +549,7 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
messageInSub.request(10)
// send half a message
val pub = TestPublisher.manualProbe[ByteString]
val pub = TestPublisher.manualProbe[ByteString]()
val msg = BinaryMessage.Streamed(Source(pub))
pushMessage(msg)
expectFrameOnNetwork(Opcode.Binary, ByteString.empty, fin = false)
@ -765,11 +765,11 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
protected def serverSide: Boolean
protected def closeTimeout: FiniteDuration = 1.second
val netIn = TestPublisher.manualProbe[ByteString]
val netIn = TestPublisher.manualProbe[ByteString]()
val netOut = TestSubscriber.manualProbe[ByteString]
val messageIn = TestSubscriber.manualProbe[Message]
val messageOut = TestPublisher.manualProbe[Message]
val messageOut = TestPublisher.manualProbe[Message]()
val messageHandler: Flow[Message, Message, Unit] =
Flow.wrap {