public override Task WriteDataAsync(IChannelHandlerContext ctx, int streamId, IByteBuffer data, int padding, bool endOfStream, IPromise promise)
        {
            if (IsExistingStream(streamId))
            {
                return(base.WriteDataAsync(ctx, streamId, data, padding, endOfStream, promise));
            }

            if (_pendingStreams.TryGetValue(streamId, out var pendingStream))
            {
                pendingStream._frames.Add(new DataFrame(this, data, padding, endOfStream, promise));
            }
            else
            {
                ReferenceCountUtil.SafeRelease(data);
                promise.SetException(ThrowHelper.GetConnectionError_StreamDoesNotExist(streamId));
            }
            return(promise.Task);
        }
 public override Task WriteRstStreamAsync(IChannelHandlerContext ctx, int streamId, Http2Error errorCode, IPromise promise)
 {
     if (IsExistingStream(streamId))
     {
         return(base.WriteRstStreamAsync(ctx, streamId, errorCode, promise));
     }
     // Since the delegate doesn't know about any buffered streams we have to handle cancellation
     // of the promises and releasing of the ByteBufs here.
     if (_pendingStreams.TryGetValue(streamId, out var stream))
     {
         _ = _pendingStreams.Remove(streamId);
         // Sending a RST_STREAM to a buffered stream will succeed the promise of all frames
         // associated with the stream, as sending a RST_STREAM means that someone "doesn't care"
         // about the stream anymore and thus there is not point in failing the promises and invoking
         // error handling routines.
         stream.Close(null);
         promise.Complete();
     }
     else
     {
         promise.SetException(ThrowHelper.GetConnectionError_StreamDoesNotExist(streamId));
     }
     return(promise.Task);
 }