Armeria: Status.UNKNOWN in attempt to connect to a closed port

Created on 12 Dec 2019  路  6Comments  路  Source: line/armeria

Hi guys,

Found a small discrepancy (unless I'm doing something wrong), when I tested Armeria gRPC client (0.88). StatusRuntimeException/UNAVAILABLE is returned if I send a request to a closed port via pure gRPC client (1.21), however Armeria client in this case returns StatusRuntimeException/UNKNOWN.

This looks misleading - the service is clearly unavailable on the closed port.

Sincerely,
Andrey

not a bug

All 6 comments

Hi @andrey-tpt, Thanks for reporting this issue.
First I've checked the status decision logic, but there is no difference. See HTTP to gRPC Status Code Mapping
for more information.

Let me reproduce this and investigate it more.
@anuraaga Do you have any guesses?

when I tested Armeria gRPC client (0.88).

@andrey-tpt Could you test it with the latest version(0.97.0) of Armeria gRPC client for clarity?

This is for when the port is closed - so there's no http status to map. In fromThrowable above we need to map the exception we see for when unable to connect at all. I think I might have found that hard and left a comment like that ;)

I got UNAVAILABLE status when a request is sent to an unavailable destination.

io.grpc.StatusRuntimeException: UNAVAILABLE
    at io.grpc.Status.asRuntimeException(Status.java:533)
    at io.grpc.stub.ClientCalls$StreamObserverToCallListenerAdapter.onClose(ClientCalls.java:447)
    at com.linecorp.armeria.client.grpc.ArmeriaClientCall.close(ArmeriaClientCall.java:410)
    at com.linecorp.armeria.client.grpc.ArmeriaClientCall.transportReportStatus(ArmeriaClientCall.java:369)
    at com.linecorp.armeria.internal.grpc.TransportStatusListener.transportReportStatus(TransportStatusListener.java:28)
    at com.linecorp.armeria.internal.grpc.HttpStreamReader.apply(HttpStreamReader.java:185)
    at com.linecorp.armeria.internal.grpc.HttpStreamReader.apply(HttpStreamReader.java:48)
    at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:930)
    at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:907)
    at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:478)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:510)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:518)
    at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1050)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: com.linecorp.armeria.client.UnprocessedRequestException: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: 127.0.0.1/127.0.0.1:8080
    at com.linecorp.armeria.client.HttpChannelPool.notifyConnect(HttpChannelPool.java:458)
    at com.linecorp.armeria.client.HttpChannelPool.lambda$connect$5(HttpChannelPool.java:331)
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:551)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
    at io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:608)
    at io.netty.util.concurrent.DefaultPromise.setFailure(DefaultPromise.java:109)
    at com.linecorp.armeria.client.HttpChannelPool.lambda$connect$6(HttpChannelPool.java:353)
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:570)
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:549)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
    at io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:608)
    at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:117)
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:321)
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:337)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:688)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:635)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:552)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:514)
    ... 4 more
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: 127.0.0.1/127.0.0.1:8080
Caused by: java.net.ConnectException: Connection refused

@andrey-tpt Could you put your full stacktrace log about StatusRuntimeException/UNKNOWN?

In fromThrowable above we need to map the exception we see for when unable to connect at all.

I think the following code covers the connection fail since the exception is wrapped with UnprocessRequestException. #1848
https://github.com/line/armeria/blob/85e7e386b7222655d9ae3cf577f0f5f77c5cae85/grpc/src/main/java/com/linecorp/armeria/internal/grpc/GrpcStatus.java#L103-L105

when I tested Armeria gRPC client (0.88).

@andrey-tpt Could you test it with the latest version(0.97.0) of Armeria gRPC client for clarity?

Thank you, guys. I can confirm that in my case with Armeria 0.97 expected status UNVAILABLE is returned from connection to a closed port. Now I need somehow to migrate from gRPC 1.21 to 1.25.

Was this page helpful?
0 / 5 - 0 ratings