Thank you for your answer :)

On Monday, March 27, 2017 at 7:19:38 PM UTC+3, Eric Anderson wrote:
>
> On Sun, Mar 26, 2017 at 9:28 AM, David Edery <da...@intuitionrobotics.com 
> <javascript:>> wrote:
>
>> 500ms is too much for my app to wait before streaming. This is why I 
>> prepare everything before and I make sure that at the end of a recognition 
>> operation the full structure is prepared for the next iteration.
>
>
> ManagedChannel connects lazily (on first RPC), and I'd expect a good 
> portion of the 500ms is creating the TCP connection and TLS. Eagerly 
> connecting will be provided by the channel state API via getState(true). 
>

It doesn't seem like we're spending more time after the wiring so I guess 
that something in the wiring flow causes the eager connectivity. The flow 
of the wiring is:
1. Create the channel using ManagedChannelBuilder (without idleTimeout for 
now)
2. Create the speech client 
(SpeechGrpc.newStub(channel).withCallCredentials(MoreCallCredentials.from(credentials)))
3. Create a response StreamObserverImpl (implements 
StreamObserver<StreamingRecognizeResponse>. This is a simple internal 
object creation so no connectivity there, I can probably skip this since 
there's no real value in creating a new instance every time but it won't 
save much of the 500ms)
4. Create a request observer (of type 
StreamObserver<StreamingRecognizeRequest>) by calling the speech client's 
(which is of type SpeechGrpc.SpeechStub) streamingRecognize function

I didn't get into the details (yet) but I'm sure that there's network 
activity in the above described flow. I know it due to an exception I got 
on network activity when this flow was executed on the main (UI) thread 
(which doesn't allow network activity to be executed on it).

 
>
>> However, I've noticed that given a long enough idle wait (don't know how 
>> long, matter of minutes) of the channel, if I try to stream the audio, 
>> everything acts as if all is well but I don't get any response (to 
>> beginning of speech nor transcripts nor any error).
>>
>
> That sounds like a network failure. Once we support keepalive without any 
> active RPCs (I'm working on this now; is about a week away; it may make the 
> next release), it could detect the failure. But using that option with 
> Google APIs is unsupported; the frontend doesn't want the additional 
> traffic. At the moment we would suggest using 
> ManagedChannelBuilder.idleTimeout 
> <http://www.grpc.io/grpc-java/javadoc/io/grpc/ManagedChannelBuilder.html#idleTimeout-long-java.util.concurrent.TimeUnit->
>  so 
> that the TCP connection is torn down during the inactive period so that it 
> isn't in a hung state when you want to do an RPC.
>

"the frontend doesn't want the addition traffic" == RPC calls are ok but 
anything else would be suspected as DDoS? (depends of course on the 
frequency of the keep alive)
 

>
> I hypothesised that it has to do with the connectivity state/idle state of 
>> the channel and decided that I'll constantly shut the channel down and 
>> reconnect in 1 minute intervals (given of course that it's not busy). This 
>> solved the problem - but it's a workaround of course.
>>
>
> I don't think the issue is caused by a gRPC state change. It's generally 
> caused by problems in the network. Using idleTimeout() will trigger gRPC to 
> shutdown the connection for you. In order to avoid the 500ms overhead 
> later, you'd need the channel state API and ask the channel to re-connect 
> each time it goes IDLE.
>

Yes. That is why I'm asking about the state API. It seems that this is the 
ideal solution for my problem 


> Is there a way to know what's the state of the channel? I saw that 
>> grpc-java issue #28 should address this issue with the 
>> ManagedChannel.getState/notifyWhenStateChanged APIs (rel 1.2.0) but it's 
>> not implemented yet.
>>
>
> Nope. Note that the API wouldn't tell you anything in this case, since the 
> problem isn't likely caused by gRPC going idle. But if it was implemented 
> it would provide you a way to "kick" gRPC to eagerly make a TCP connection.
>

A:
So if I understand correctly (and please correct me if I'm wrong), once 
state API is available the flow would be something like:
1. create the channel (as described above) with idleTimeout + listener on 
connectivity state change
2. In case of connectivity state change, goto #1
3. prior to using the channel, call getState(true) to eagerly connect it 
(in case that idleTimeout was reached) if is not connected and then do the 
actual streaming work 

B:
Today, in step #1 (that doesn't include idleTimeout), if channel != null && 
!channel.isShutdown && !channel.isTerminated I call channel.shutdownNow and 
immediately create a new ManagedChannel (which means - the way I understand 
it - that there's a channel in the process of shutting down while 
immediately I create another channel which is wiring up). Just to validate 
this point - is this described flow is ok? (shutdown one channel instance 
while creating another channel for the same host).

Given the future A and the current B, I assume that I will still need to 
take care for the channel shutdown at the end of the streaming operation. 
idleTimeout will not take care for it once the channel has been active no? 
from the documentation of idleTimeout: "By default the channel will never 
go to idle mode after it leaves the initial idle mode". Is this a correct 
assumption?
Does the above flow (A+B) sounds reasonable as a solution to an 
always-ready channel requirement?


> I also saw that there's a health check protocol (
>> https://github.com/grpc/grpc/blob/master/doc/health-checking.md) - does 
>> this feature work? would it be suitable for my needs?
>>
>
> That's more for load balancing (avoiding backends that aren't healthy). It 
> wouldn't help you, as I don't think our public APIs provide such a service.
>

cool
 

>
> When is the state API is expected to land? I think that going forward this 
>> is the way to go from our app's perspective.
>>
>
> It's currently scheduled for Q2. That isn't a promise, but gives an idea.
>

Thanks. It is much expected. 

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to grpc-io+unsubscr...@googlegroups.com.
To post to this group, send email to grpc-io@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/5f153a1b-1b64-4b94-bc48-b6b7046a0b7f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to