netty5/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2StreamChannelId.java
Scott Mitchell 911b2acc50 HTTP/2 Child Channel reading and flushing
Motivation:
If a child channel's read is triggered outside the parent channel's read
loop then it is possible a WINDOW_UPDATE will be written, but not
flushed.
If a child channel's beginRead processes data from the inboundBuffer and
then readPending is set to false, which will result in data not being
delivered if in the parent's read loop and more data is attempted to be
delievered to that child channel.

Modifications:
- The child channel must force a flush if a frame is written as a result
of reading a frame, and this is not in the parent channel's read loop
- The child channel must allow a transition from dequeueing from
beginRead into the parent channel's read loop to deliver more data

Result:
The child channel flushes data when reading outside the parent's read
loop, and has frames delivered more reliably.
2017-10-26 10:06:22 -07:00

77 lines
2.2 KiB
Java

/*
* Copyright 2017 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.codec.http2;
import io.netty.channel.ChannelId;
/**
* ChannelId implementation which is used by our {@link Http2StreamChannel} implementation.
*/
final class Http2StreamChannelId implements ChannelId {
private static final long serialVersionUID = -6642338822166867585L;
private final int id;
private final ChannelId parentId;
Http2StreamChannelId(ChannelId parentId, int id) {
this.parentId = parentId;
this.id = id;
}
@Override
public String asShortText() {
return parentId.asShortText() + '/' + id;
}
@Override
public String asLongText() {
return parentId.asLongText() + '/' + id;
}
@Override
public int compareTo(ChannelId o) {
if (o instanceof Http2StreamChannelId) {
Http2StreamChannelId otherId = (Http2StreamChannelId) o;
int res = parentId.compareTo(otherId.parentId);
if (res == 0) {
return id - otherId.id;
} else {
return res;
}
}
return parentId.compareTo(o);
}
@Override
public int hashCode() {
return id * 31 + parentId.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Http2StreamChannelId)) {
return false;
}
Http2StreamChannelId otherId = (Http2StreamChannelId) obj;
return id == otherId.id && parentId.equals(otherId.parentId);
}
@Override
public String toString() {
return asShortText();
}
}