Open
Description
Hello, we have an app, that implements a widget that gets data using a GRPC stream on an update. However we have many instances where the widget fails to update where we are receiving:
io.grpc.StatusRuntimeException: UNAVAILABLE: Keepalive failed. The connection is likely gone
at io.grpc.Status.asRuntimeException(Status.java:533)
at io.grpc.stub.ClientCalls$BlockingResponseStream.hasNext(ClientCalls.java:629)
at kotlin.sequences.SequencesKt___SequencesKt.toCollection(_Sequences.kt:722)
at kotlin.sequences.SequencesKt___SequencesKt.toMutableList(_Sequences.kt:752)
at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:743)
we are building our channel with the following parameters:
AndroidChannelBuilder.forAddress("<backend-url-->", 443)
.context(context)
.keepAliveWithoutCalls(true)
.keepAliveTime(5, TimeUnit.SECONDS)
.keepAliveTimeout(5, TimeUnit.SECONDS)
.useTransportSecurity()
.intercept(MetadataInterceptor())
.build()
and we care calling our stream collection using:
clientWalletCall =
channel.newCall(ChartsServiceGrpc.getGetWalletLiveChartMethod(), service.callOptions)
I am assuming, when the app goes the background (due to the user's OS setting restricting background data) that the main grpc channel gets broken and needs time to restart, so when the widget wakes up to update, the call fails.
What is the best way to address this issue where we need block till the channel is ready to ensure the stream is successful?
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
sanjaypujare commentedon May 19, 2021
Take a look at https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md and you want to wait until the channel is READY. You can use
ManagedChannel.getState()
to get the current state of the channel and useManagedChannel.notifyWhenStateChanged()
to be notified when the channel is READY to achieve your blocking.jchau207 commentedon May 20, 2021
Is this similar to withWaitForReady? How long does withWaitForReady blocked for and does it respect withDeadline as well?
sanjaypujare commentedon May 20, 2021
Yes, you can use
withWaitForReady
. The semantics are described in https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.mdejona86 commentedon May 26, 2021
CC @dapengzhang0
dapengzhang0 commentedon May 26, 2021
withWaitForReady
should work if the call is started after the wakeup.If a call was started and received part of the response just milliseconds before the app goes to the background, I'm not sure what Android would do then, but if you see "UNAVAILABLE: Keepalive failed. The connection is likely gone" after the wakeup, then unfortunately there is nothing grpc library can do.
jchau207 commentedon May 26, 2021
Thank you for the response, If the call goes: "UNAVAILABLE: Keepalive failed. The connection is likely gone" what exactly is the connection state? From observation, the channel does eventually fix it self so I should expect withWaitForReady work for the scenario.
From our experience using GRPC in app development, we find that many users restrict background data usage on their phone and the GRPC channel kinda goes berserk when the app is in the background ping ponging between Transient Failures and Connecting. Are there any plans to allow the channel be more application life cycle aware and park channel state in a state that is quicker or reliable to reconnect after wake up?
ejona86 commentedon Aug 2, 2021
At the time of the RPC it was READY, but it transitioned to TRANSIENT_FAILURE.
I think the most appropriate thing to do here is
channel.enterIdle()
which will drop the connection. If there's an existing RPC though, there may be something better depending on if the network is already cut off. It isn't clear to me what the appropriate notifications to listen for are. I seeActivity.onUserLeaveHint()
may be relevant, but it'd take some more digging to see if there's not other things that are more appropriate.[-]Android widget updates with GRPC[/-][+]android: Disabled background data causes errors[/+]