Class Http2Demux
- java.lang.Object
-
- akka.stream.stage.GraphStageWithMaterializedValue<akka.stream.BidiShape<Http2SubStream,FrameEvent,FrameEvent,Http2SubStream>,ServerTerminator>
-
- akka.http.impl.engine.http2.Http2Demux
-
- All Implemented Interfaces:
akka.stream.Graph<akka.stream.BidiShape<Http2SubStream,FrameEvent,FrameEvent,Http2SubStream>,ServerTerminator>
- Direct Known Subclasses:
Http2ClientDemux
,Http2ServerDemux
public abstract class Http2Demux extends akka.stream.stage.GraphStageWithMaterializedValue<akka.stream.BidiShape<Http2SubStream,FrameEvent,FrameEvent,Http2SubStream>,ServerTerminator>
INTERNAL APIThis stage contains all control logic for handling frames and (de)muxing data to/from substreams.
The BidiStage consumes and produces FrameEvents from the network. It will output one Http2SubStream for incoming frames per substream and likewise accepts a single Http2SubStream per substream with outgoing frames.
(An alternative API would just push a BidiHttp2SubStream(subStreamFlow: Flow[StreamFrameEvent, StreamFrameEvent]) similarly to IncomingConnection. This would more accurately model the one-to-one relation between incoming and outgoing Http2Substream directions but wouldn't stack so nicely with other BidiFlows.)
Backpressure logic:
* read all incoming frames without applying backpressure * this ensures that all "control" frames are read in a timely manner * though, make sure limits are not exceeded * max connection limit (which limits number of parallel requests) * window sizes for incoming data frames * that means we need to buffer incoming substream data until the user handler (consuming the source in the Http2SubStream) will read it * per-connection and per-stream window updates should reflect how much data was (not) yet passed into the user handler and therefore are the main backpressure mechanism towards the peer * for the outgoing frame side we need to decide which frames to send per incoming demand * control frames (settings, ping, acks, window updates etc.) -> responses to incoming frames * substream frames -> incoming frame data from substreams * to be able to make a decision some data must already be buffered for those two sources of incoming frames
Demultiplexing: * distribute incoming frames to their respective targets: * control frames: handled internally, may generate outgoing control frames directly * incoming HEADERS frames: creates a new Http2SubStream including a SubSource that will receive all upcoming data frames * incoming data frames: buffered and pushed to the SubSource of the respective substream
Multiplexing: * schedule incoming frames from multiple sources to be pushed onto the shared medium * control frames: as generated from the stage itself (should probably preferred over everything else) * Http2SubStream produced by the user handler: read and push initial frame ASAP * outgoing data frames for each of the substreams: will comprise the bulk of the data and is where any clever, prioritizing, etc. i.e. tbd later sending strategies will apply
In the best case we could just flattenMerge the outgoing side (hoping for the best) but this will probably not work because the sending decision relies on dynamic window size and settings information that will be only available in this stage.
param: initialRemoteSettings sequence of settings received on the initial header sent from the client in an ' HTTP2-Settings:' header. This parameter should only be used on the server end of a connection.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
Http2Demux.CompletionTimeout$
-
Constructor Summary
Constructors Constructor Description Http2Demux(Http2CommonSettings http2Settings, scala.collection.immutable.Seq<FrameEvent.Setting> initialRemoteSettings, boolean upgraded, boolean isServer)
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description abstract scala.concurrent.duration.FiniteDuration
completionTimeout()
scala.Tuple2<akka.stream.stage.GraphStageLogic,ServerTerminator>
createLogicAndMaterializedValue(akka.stream.Attributes inheritedAttributes)
akka.stream.Inlet<FrameEvent>
frameIn()
akka.stream.Outlet<FrameEvent>
frameOut()
akka.stream.BidiShape<Http2SubStream,FrameEvent,FrameEvent,Http2SubStream>
shape()
akka.stream.Inlet<Http2SubStream>
substreamIn()
akka.stream.Outlet<Http2SubStream>
substreamOut()
abstract scala.Option<HttpEntity.ChunkStreamPart>
wrapTrailingHeaders(FrameEvent.ParsedHeadersFrame headers)
-
-
-
Constructor Detail
-
Http2Demux
public Http2Demux(Http2CommonSettings http2Settings, scala.collection.immutable.Seq<FrameEvent.Setting> initialRemoteSettings, boolean upgraded, boolean isServer)
-
-
Method Detail
-
frameIn
public akka.stream.Inlet<FrameEvent> frameIn()
-
frameOut
public akka.stream.Outlet<FrameEvent> frameOut()
-
substreamOut
public akka.stream.Outlet<Http2SubStream> substreamOut()
-
substreamIn
public akka.stream.Inlet<Http2SubStream> substreamIn()
-
shape
public akka.stream.BidiShape<Http2SubStream,FrameEvent,FrameEvent,Http2SubStream> shape()
-
wrapTrailingHeaders
public abstract scala.Option<HttpEntity.ChunkStreamPart> wrapTrailingHeaders(FrameEvent.ParsedHeadersFrame headers)
-
completionTimeout
public abstract scala.concurrent.duration.FiniteDuration completionTimeout()
-
createLogicAndMaterializedValue
public scala.Tuple2<akka.stream.stage.GraphStageLogic,ServerTerminator> createLogicAndMaterializedValue(akka.stream.Attributes inheritedAttributes)
- Specified by:
createLogicAndMaterializedValue
in classakka.stream.stage.GraphStageWithMaterializedValue<akka.stream.BidiShape<Http2SubStream,FrameEvent,FrameEvent,Http2SubStream>,ServerTerminator>
-
-