use of com.webpieces.http2engine.impl.DataTry in project webpieces by deanhiller.
the class Level6RemoteFlowControl method sendDataToSocket.
public CompletableFuture<Void> sendDataToSocket(Stream stream, DataFrame dataFrame) {
log.info("sending payload to socket=" + dataFrame);
CompletableFuture<Void> future = new CompletableFuture<>();
DataTry data = new DataTry(stream, dataFrame, future, false);
trySendPayload(data);
return future;
}
use of com.webpieces.http2engine.impl.DataTry in project webpieces by deanhiller.
the class Level6RemoteFlowControl method updateConnectionWindowSize.
public CompletableFuture<Void> updateConnectionWindowSize(WindowUpdateFrame msg) {
int increment = msg.getWindowSizeIncrement();
if (increment == 0) {
throw new ConnectionException(CancelReasonCode.WINDOW_SIZE_INVALID, logId, msg.getStreamId(), "Received windowUpdate size increment=0");
}
DataTry dataTry = null;
DataTry temp = dataQueue.peek();
synchronized (remoteLock) {
// we should delete this synchronized as we are virtually single threaded now!!!
remoteWindowSize += increment;
if (remoteWindowSize > Integer.MAX_VALUE)
throw new ConnectionException(CancelReasonCode.FLOW_CONTROL_ERROR, logId, 0, "(remote end bad)global remoteWindowSize too large=" + remoteWindowSize + " from windows increment=" + increment);
if (temp != null && remoteWindowSize > temp.getDataFrame().getTransmitFrameLength())
dataTry = dataQueue.poll();
log.info("updated window to=" + remoteWindowSize + " increment=" + msg.getWindowSizeIncrement() + " dataTry to submit=" + dataTry);
}
if (dataTry != null) {
dataTry.setWasQueuedBefore(true);
trySendPayload(dataTry);
}
return CompletableFuture.completedFuture(null);
}
use of com.webpieces.http2engine.impl.DataTry in project webpieces by deanhiller.
the class Level6RemoteFlowControl method updateStreamWindowSize.
public CompletableFuture<Void> updateStreamWindowSize(Stream stream, WindowUpdateFrame msg) {
if (msg.getWindowSizeIncrement() == 0) {
throw new ConnectionException(CancelReasonCode.WINDOW_SIZE_INVALID, logId, msg.getStreamId(), "Received windowUpdate size increment=0");
}
DataTry dataTry = null;
DataTry temp = dataQueue.peek();
synchronized (remoteLock) {
long remoteWindowSize = stream.incrementRemoteWindow(msg.getWindowSizeIncrement());
if (temp != null && remoteWindowSize > temp.getDataFrame().getTransmitFrameLength())
dataTry = dataQueue.poll();
log.info("updated stream " + stream.getStreamId() + " window to=" + stream.getRemoteWindowSize() + " increment=" + msg.getWindowSizeIncrement() + " dataTry to submit=" + dataTry);
}
if (dataTry != null) {
dataTry.setWasQueuedBefore(true);
trySendPayload(dataTry);
}
//someday, remove synchronized above and then complete future when it is complete instead maybe
return CompletableFuture.completedFuture(null);
}
use of com.webpieces.http2engine.impl.DataTry in project webpieces by deanhiller.
the class Level6RemoteFlowControl method trySendPayload.
private void trySendPayload(DataTry data) {
long length = data.getDataFrame().getTransmitFrameLength();
Stream stream = data.getStream();
boolean send;
long min = Math.min(remoteWindowSize, stream.getRemoteWindowSize());
long lengthToSend = Math.min(length, min);
if (length != lengthToSend) {
//must split DataFrame into two since WindowUpdateSize is not large enough
List<DataTry> tuple = splitDataFrame(data, lengthToSend);
//swap the right size to send
data = tuple.get(0);
dataQueue.add(0, tuple.get(1));
}
if (lengthToSend > 0) {
stream.incrementRemoteWindow(-lengthToSend);
remoteWindowSize -= lengthToSend;
send = true;
} else if (data.isWasQueuedBefore()) {
//insert BACK at beginning of queue
dataQueue.add(0, data);
send = false;
} else {
//insert at end of queue
dataQueue.add(data);
send = false;
}
log.info("flow control. send=" + send + " window=" + remoteWindowSize + " streamWindow=" + stream.getRemoteWindowSize());
if (send) {
DataTry finalTry = data;
layer6NotifyListener.sendFrameToSocket(data.getDataFrame()).handle((v, t) -> processComplete(v, t, finalTry.getFuture()));
}
}
use of com.webpieces.http2engine.impl.DataTry in project webpieces by deanhiller.
the class Level6RemoteFlowControl method splitDataFrame.
private List<DataTry> splitDataFrame(DataTry dataTry, long lengthToSend) {
if (lengthToSend > Integer.MAX_VALUE)
throw new IllegalStateException("bug, length to send should not be this large(per spec)=" + lengthToSend);
int len = (int) lengthToSend;
DataFrame dataFrame = dataTry.getDataFrame();
DataWrapper data = dataFrame.getData();
if (dataFrame.getPadding().getReadableSize() > 0)
throw new UnsupportedOperationException("Splitting padding under these conditions would be" + " quite difficult so we skipped it. perhaps stop using padding or" + " modify this code but some padding would have to go in one" + " DataFrame and the rest in the next as the window size is not large enough");
List<? extends DataWrapper> split = dataGen.split(data, len);
DataFrame dF1 = new DataFrame();
dF1.setData(split.get(0));
DataFrame dF2 = new DataFrame();
dF2.setData(split.get(1));
List<DataTry> tuple = new ArrayList<>();
tuple.add(new DataTry(dataTry.getStream(), dF1, null, dataTry.isWasQueuedBefore()));
tuple.add(new DataTry(dataTry.getStream(), dF2, dataTry.getFuture(), dataTry.isWasQueuedBefore()));
return tuple;
}
Aggregations