Open dmytro-lazebnyi opened 5 years ago
Tried to reproduce it in https://github.com/scalecube/scalecube-gateway/pull/89. Instead found a buffer leak (and fixed it) on new tests. The scenarios (on all gateway-client-transport protocols) to verify a situation when ServiceCall is calling gateway address but on that address nobody is listening.
This one is related -- https://github.com/spring-cloud/spring-cloud-gateway/issues/280. Looks like tihs is prroblem with reactor-netty bug in ChannelOoperations.onComplete()
not calling onOutboundComplete
and not sending LastHttpContent
to HttpObjectEncoder
, and by turn leaving http channel in broken state (i.e still INIT).
Found very much related issues: https://github.com/reactor/reactor-netty/issues/361, https://github.com/reactor/reactor-netty/issues/177.
Looping @snripa. From what ppl already posting to them in existing issues is very much looks like (IMHO) that reactor-netty doesn't send LastHttpContent
neither from HttpClientOperations#onOutboundComplete()
neither from HttpServerOperations#onOutboundComplete()
. Though both began from reactor.netty.channel.ChannelOperations#onComplete()
. Looks like this block in ChannelOperations
on lines 197-199 (on reactory-netty master
branch) is the root cause:
@Override
public final void onComplete() {
if (isDisposed()) {
return;
}
...
}
ChannelOperations
impl. Subscriber
, that's why his onComplete() function must adhere to semantics of org.reactivestreams.Subscriber#onComplete()
, i.e dispose on exception (among everything else). Hence it very looks like that when exception occurred it doesn't send LastHttpContent
to io.netty.handler.codec.http.HttpObjectEncoder
there by leaving him in wrong state.
I suggest as a resolution to this ticket is to write test psmv
program which would reproduce this issue and send it to them + make sure they accepted it.
Stacktrace
``` E 2019-09-09T11:55:00,269 i.s.s.g.w.WebsocketGatewayAcceptor Exception occurred on request: GatewayMessage {headers: {q=/om2.exchange.auth/createSession, sessionId=1568023078647, sid=1}, data: bb-670}, session=1568023078647 [http-gateway-client-epoll-4] ... 25 more at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:89) ~[netty-codec-4.1.36.Final.jar:4.1.36.Final] at io.netty.handler.codec.http.HttpClientCodec$Encoder.encode(HttpClientCodec.java:167) ~[netty-codec-http-4.1.36.Final.jar:4.1.36.Final] at io.netty.handler.codec.http.HttpObjectEncoder.encode(HttpObjectEncoder.java:86) ~[netty-codec-http-4.1.36.Final.jar:4.1.36.Final] Caused by: java.lang.IllegalStateException: unexpected message type: DefaultFullHttpRequest, state: 1 at java.lang.Thread.run(Thread.java:748) [?:1.8.0_222] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.36.Final.jar:4.1.36.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:906) ~[netty-common-4.1.36.Final.jar:4.1.36.Final] at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:338) ~[netty-transport-native-epoll-4.1.36.Final-linux-x86_64.jar:4.1.36.Final] at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:405) ~[netty-common-4.1.36.Final.jar:4.1.36.Final] at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) ~[netty-common-4.1.36.Final.jar:4.1.36.Final] at reactor.netty.resources.PooledConnectionProvider$DisposableAcquire.run(PooledConnectionProvider.java:566) ~[reactor-netty-0.8.8.RELEASE.jar:0.8.8.RELEASE] at reactor.netty.ReactorNetty$CompositeConnectionObserver.onStateChange(ReactorNetty.java:470) ~[reactor-netty-0.8.8.RELEASE.jar:0.8.8.RELEASE] at reactor.netty.http.client.HttpClientConnect$HttpIOHandlerObserver.onStateChange(HttpClientConnect.java:441) ~[reactor-netty-0.8.8.RELEASE.jar:0.8.8.RELEASE] at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.2.9.RELEASE.jar:3.2.9.RELEASE] at reactor.core.publisher.MonoSource.subscribe(MonoSource.java:51) ~[reactor-core-3.2.9.RELEASE.jar:3.2.9.RELEASE] at reactor.netty.NettyOutbound.subscribe(NettyOutbound.java:305) ~[reactor-netty-0.8.8.RELEASE.jar:0.8.8.RELEASE] at reactor.core.publisher.Mono.subscribe(Mono.java:3710) ~[reactor-core-3.2.9.RELEASE.jar:3.2.9.RELEASE] at reactor.core.publisher.MonoSubscriberContext.subscribe(MonoSubscriberContext.java:47) ~[reactor-core-3.2.9.RELEASE.jar:3.2.9.RELEASE] at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:53) ~[reactor-core-3.2.9.RELEASE.jar:3.2.9.RELEASE] at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:141) ~[reactor-core-3.2.9.RELEASE.jar:3.2.9.RELEASE] at reactor.netty.http.HttpOperations.lambda$send$0(HttpOperations.java:104) ~[reactor-netty-0.8.8.RELEASE.jar:0.8.8.RELEASE] at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:305) ~[netty-transport-4.1.36.Final.jar:4.1.36.Final] at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1036) ~[netty-transport-4.1.36.Final.jar:4.1.36.Final] at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:812) ~[netty-transport-4.1.36.Final.jar:4.1.36.Final] at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:757) ~[netty-transport-4.1.36.Final.jar:4.1.36.Final] at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:789) ~[netty-transport-4.1.36.Final.jar:4.1.36.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:763) ~[netty-transport-4.1.36.Final.jar:4.1.36.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:716) ~[netty-transport-4.1.36.Final.jar:4.1.36.Final] at io.netty.channel.CombinedChannelDuplexHandler.write(CombinedChannelDuplexHandler.java:348) ~[netty-transport-4.1.36.Final.jar:4.1.36.Final] at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107) ~[netty-codec-4.1.36.Final.jar:4.1.36.Final] io.netty.handler.codec.EncoderException: java.lang.IllegalStateException: unexpected message type: DefaultFullHttpRequest, state: 1 ```