!str #16410 #16597: Removed TimerTransform, added Timeout stages

This commit is contained in:
Endre Sándor Varga 2015-09-11 15:50:17 +02:00
parent d5b5e6f22d
commit 12c9abb8c9
25 changed files with 1185 additions and 679 deletions

View file

@ -127,6 +127,53 @@ package object util {
package util {
import akka.http.scaladsl.model.{ ContentType, HttpEntity }
import akka.stream.{ Outlet, Inlet, FlowShape }
import scala.concurrent.duration.FiniteDuration
private[http] class ToStrict(timeout: FiniteDuration, contentType: ContentType)
extends GraphStage[FlowShape[ByteString, HttpEntity.Strict]] {
val in = Inlet[ByteString]("in")
val out = Outlet[HttpEntity.Strict]("out")
override val shape = FlowShape(in, out)
override def createLogic: GraphStageLogic = new GraphStageLogic {
var bytes = ByteString.newBuilder
private var emptyStream = false
scheduleOnce("ToStrictTimeoutTimer", timeout)
setHandler(out, new OutHandler {
override def onPull(): Unit = {
if (emptyStream) {
push(out, HttpEntity.Strict(contentType, ByteString.empty))
completeStage()
} else pull(in)
}
})
setHandler(in, new InHandler {
override def onPush(): Unit = {
bytes ++= grab(in)
pull(in)
}
override def onUpstreamFinish(): Unit = {
if (isAvailable(out)) {
push(out, HttpEntity.Strict(contentType, bytes.result()))
completeStage()
} else emptyStream = true
}
})
override def onTimer(key: Any): Unit =
failStage(new java.util.concurrent.TimeoutException(
s"HttpEntity.toStrict timed out after $timeout while still waiting for outstanding data"))
}
override def toString = "ToStrict"
}
private[http] class EventStreamLogger extends Actor with ActorLogging {
def receive = { case x log.warning(x.toString) }
}

View file

@ -13,11 +13,10 @@ import scala.concurrent.Future
import scala.concurrent.duration._
import scala.collection.immutable
import akka.util.ByteString
import akka.stream.Materializer
import akka.stream.{ ActorMaterializer, Materializer }
import akka.stream.scaladsl._
import akka.stream.io.SynchronousFileSource
import akka.stream.io.{ Timeouts, SynchronousFileSource }
import akka.{ japi, stream }
import akka.stream.TimerTransformer
import akka.http.scaladsl.util.FastFuture
import akka.http.javadsl.{ model jm }
import akka.http.impl.util.JavaMapping.Implicits._
@ -55,28 +54,10 @@ sealed trait HttpEntity extends jm.HttpEntity {
* Collects all possible parts and returns a potentially future Strict entity for easier processing.
* The Future is failed with an TimeoutException if the stream isn't completed after the given timeout.
*/
def toStrict(timeout: FiniteDuration)(implicit fm: Materializer): Future[HttpEntity.Strict] = {
def transformer() =
new TimerTransformer[ByteString, HttpEntity.Strict] {
var bytes = ByteString.newBuilder
scheduleOnce("", timeout)
def onNext(element: ByteString): immutable.Seq[HttpEntity.Strict] = {
bytes ++= element
Nil
}
override def onTermination(e: Option[Throwable]): immutable.Seq[HttpEntity.Strict] =
HttpEntity.Strict(contentType, bytes.result()) :: Nil
def onTimer(timerKey: Any): immutable.Seq[HttpEntity.Strict] =
throw new java.util.concurrent.TimeoutException(
s"HttpEntity.toStrict timed out after $timeout while still waiting for outstanding data")
}
// TODO timerTransform is meant to be replaced / rewritten, it's currently private[akka]; See https://github.com/akka/akka/issues/16393
dataBytes.via(Flow[ByteString].timerTransform(transformer).named("toStrict")).runWith(Sink.head)
}
def toStrict(timeout: FiniteDuration)(implicit fm: Materializer): Future[HttpEntity.Strict] =
dataBytes
.via(new akka.http.impl.util.ToStrict(timeout, contentType))
.runWith(Sink.head)
/**
* Returns a copy of the given entity with the ByteString chunks of this entity transformed by the given transformer.