use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.
the class AbstractFlowControlStrategy method updateInitialStreamWindow.
@Override
public void updateInitialStreamWindow(ISession session, int initialStreamWindow, boolean local) {
int previousInitialStreamWindow;
if (local) {
previousInitialStreamWindow = getInitialStreamRecvWindow();
this.initialStreamRecvWindow = initialStreamWindow;
} else {
previousInitialStreamWindow = getInitialStreamSendWindow();
this.initialStreamSendWindow = initialStreamWindow;
}
int delta = initialStreamWindow - previousInitialStreamWindow;
// SPEC: updates of the initial window size only affect stream windows, not session's.
for (Stream stream : session.getStreams()) {
if (local) {
((IStream) stream).updateRecvWindow(delta);
if (LOG.isDebugEnabled())
LOG.debug("Updated initial stream recv window {} -> {} for {}", previousInitialStreamWindow, initialStreamWindow, stream);
} else {
session.onWindowUpdate((IStream) stream, new WindowUpdateFrame(stream.getId(), delta));
}
}
}
use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.
the class BufferingFlowControlStrategy method onDataConsumed.
@Override
public void onDataConsumed(ISession session, IStream stream, int length) {
if (length <= 0)
return;
float ratio = bufferRatio;
WindowUpdateFrame windowFrame = null;
int level = sessionLevel.addAndGet(length);
int maxLevel = (int) (maxSessionRecvWindow.get() * ratio);
if (level > maxLevel) {
if (sessionLevel.compareAndSet(level, 0)) {
session.updateRecvWindow(level);
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, {} bytes, updated session recv window by {}/{} for {}", length, level, maxLevel, session);
windowFrame = new WindowUpdateFrame(0, level);
} else {
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, {} bytes, concurrent session recv window level {}/{} for {}", length, sessionLevel, maxLevel, session);
}
} else {
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, {} bytes, session recv window level {}/{} for {}", length, level, maxLevel, session);
}
Frame[] windowFrames = Frame.EMPTY_ARRAY;
if (stream != null) {
if (stream.isClosed()) {
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, {} bytes, ignoring update stream recv window for closed {}", length, stream);
} else {
AtomicInteger streamLevel = streamLevels.get(stream);
if (streamLevel != null) {
level = streamLevel.addAndGet(length);
maxLevel = (int) (getInitialStreamRecvWindow() * ratio);
if (level > maxLevel) {
level = streamLevel.getAndSet(0);
stream.updateRecvWindow(level);
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, {} bytes, updated stream recv window by {}/{} for {}", length, level, maxLevel, stream);
WindowUpdateFrame frame = new WindowUpdateFrame(stream.getId(), level);
if (windowFrame == null)
windowFrame = frame;
else
windowFrames = new Frame[] { frame };
} else {
if (LOG.isDebugEnabled())
LOG.debug("Data consumed, {} bytes, stream recv window level {}/{} for {}", length, level, maxLevel, stream);
}
}
}
}
if (windowFrame != null)
session.frames(stream, Callback.NOOP, windowFrame, windowFrames);
}
use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.
the class HTTP2Session method newStream.
@Override
public void newStream(HeadersFrame frame, Promise<Stream> promise, Stream.Listener listener) {
// Synchronization is necessary to atomically create
// the stream id and enqueue the frame to be sent.
boolean queued;
synchronized (this) {
int streamId = frame.getStreamId();
if (streamId <= 0) {
streamId = streamIds.getAndAdd(2);
PriorityFrame priority = frame.getPriority();
priority = priority == null ? null : new PriorityFrame(streamId, priority.getParentStreamId(), priority.getWeight(), priority.isExclusive());
frame = new HeadersFrame(streamId, frame.getMetaData(), priority, frame.isEndStream());
}
final IStream stream = createLocalStream(streamId, promise);
if (stream == null)
return;
stream.setListener(listener);
ControlEntry entry = new ControlEntry(frame, stream, new PromiseCallback<>(promise, stream));
queued = flusher.append(entry);
}
// Iterate outside the synchronized block.
if (queued)
flusher.iterate();
}
use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.
the class HTTP2Session method createRemoteStream.
protected IStream createRemoteStream(int streamId) {
// SPEC: exceeding max concurrent streams is treated as stream error.
while (true) {
int remoteCount = remoteStreamCount.get();
int maxCount = getMaxRemoteStreams();
if (maxCount >= 0 && remoteCount >= maxCount) {
reset(new ResetFrame(streamId, ErrorCode.REFUSED_STREAM_ERROR.code), Callback.NOOP);
return null;
}
if (remoteStreamCount.compareAndSet(remoteCount, remoteCount + 1))
break;
}
IStream stream = newStream(streamId, false);
// SPEC: duplicate stream is treated as connection error.
if (streams.putIfAbsent(streamId, stream) == null) {
updateLastStreamId(streamId);
stream.setIdleTimeout(getStreamIdleTimeout());
flowControl.onStreamCreated(stream);
if (LOG.isDebugEnabled())
LOG.debug("Created remote {}", stream);
return stream;
} else {
close(ErrorCode.PROTOCOL_ERROR.code, "duplicate_stream", Callback.NOOP);
return null;
}
}
use of org.eclipse.jetty.http2.IStream in project jetty.project by eclipse.
the class HTTP2Session method priority.
@Override
public int priority(PriorityFrame frame, Callback callback) {
int streamId = frame.getStreamId();
IStream stream = streams.get(streamId);
if (stream == null) {
streamId = streamIds.getAndAdd(2);
frame = new PriorityFrame(streamId, frame.getParentStreamId(), frame.getWeight(), frame.isExclusive());
}
control(stream, callback, frame);
return streamId;
}
Aggregations