Writing Streaming services with gRPC

In my last article here I explained how to write your own gRPC service(please go through it before starting this tutorial).

However there are a number of features in gRPC using which can be used for better performance. One such feature is streaming and we are going to implement streaming in gRPC using generators in python.

Generators in Python

Generators are iterators which return values only on demand. They use the keyword yield for returning values. They’re evaluated lazily and do not block upon invocation.

Implementing Fibonacci with Generators

You could almost everything that you do in a generator in a loop, however in some cases generators actually end up being more performant as compared to a loop. Consider the code below:

This is a simple function which returns the first 10 fibonacci numbers.

This evaluates the fibonacci numbers as soon as the function will be invoked. Essentially your program execution will block till this function executes completely.

Now we implement the above function using a generator:

Invoking this function will return a generator object that needs to be iterated to get results from:

As you can see you get a generator object(which can be iterated over in python). Once you do iterate over it, you get all the results.

Using Generators with gRPC

You can clone the gRPC example from here. We will be making changes from where we left the last tutorial.

We will be implementing a service which takes a sentence, digests it and streams the digest for each word separately(in order though).

Edit the Proto definition to add an additional RPC

We need to start editing our proto file under the name of digestor.proto.

Currently the file has only a single rpc declared in it. It looks like this:

We need to add another rpc which supports streaming and implement it in the server as well as the client.

To specify a streaming service in gRPC  we use the keyword stream in the proto file to specify the streaming.

Since we are using same the message protocol buffers that are already declared, we don’t need to declare anything else, other than declaring the rpc.

Generate protocol definition for the new proto file

Use the below give command to actually generate gRPC stubs for python as follows:

Check out the previous tutorial here to see how to setup this up.

Implement the actual rpc in the server

This is where we write the actual implementation of the the GetDStream rpc. The digest_server.py is where the implementation of the all the rpc’s live.

Adding the rpc to the client

Once we have added the implementation to the server, we also need to add the caller method to the client as well. If we don’t do this we won’t be able to call our remote procedure call remotely. Modify the the digestor_server.py to ensure the contents look like this:

Testing out the streaming rpc

With the server running in another console(but in the same virtualenv), fire up the python interpreter, and write the following:

Call the all the get_streaming_digest function on the client object to invoke the gRPC. For example:

This should return the following

You can find the code here . It is under the branch streaming.

Further

This is an excellent way to build long running network calls which are iterative in nature, as well make them performant.

I have faced a bit of random GO-AWAY errors with gRPC while using it production. I would love to here incase anyone has experienced the same.

I am a developer and tech enthusiast based out of New Delhi, India. I love python , have a love-hate relationship with Javascript, and feel that filing out tax forms are easier than Java.

1 Comment

Leave a Reply