2

I am having an issue with a lightweight gRPC server I'm writing in NodeJS. I'm referencing the documentation here. I have been able to compile my proto files representing messages and services, and have successfully stood up a gRPC server with a server-side stream method I am able to trigger via BloomRPC.

I have a proto message called parcel, which has one field: parcel_id. I want this method to stream a parcel of data every second. My first rudimentary pass at this was a loop that executes every second for a minute, and applies a new parcel via call.write(parcel). I've included the method below, it executes with no errors when I invoke it via gRPC.

/**
 * Implements the updateParcel RPC method.
 * Feeds new parcel to the passed in "call" param
 * until the simulation is stopped.
 */
function updateParcels(call) {
  console.log("Parcels requested...");

  // Continuously stream parcel protos to requester
  let i = 0;
  let id = 0;
  while(i < 60){
    // Create dummy parcel
    let parcel = new messages.Parcel();
    parcel.setParcelId(id);
    id++;// Increment id

    // Write parcel to call object
    console.log("Sending parcel...");
    call.write(parcel);

    // Sleep for a second (1000 millis) before repeating
    sleep(1000);
  }
  call.end();
}

My issue is that, although I am able to call my methods and receive results, the behavior is that I receive the first result immediately on the client (for both NodeJS client code and BloomRPC calls), but receive the last 59 results all at once only after the server executes call.end(). There are no errors, and the parcel objects I receive on the client are accurate and formatted correctly, they are just batched as described.

How can I achieve a constant stream of my parcels in real time? Is this possible? I've looked but can't tell for sure - do gRPC server-side streams have a batching behavior by default? I've tried my best to understand the gRPC documentation, but I can't tell if I'm simply trying to force gRPC server-side streams to do something they weren't designed to do. Thanks for any help, and let me know if I can provide any more information, as this is my first gRPC related SO question and I may have missed some relevant information.

ThePartyTurtle
  • 2,276
  • 2
  • 18
  • 32
  • 1
    It could be unrelated to gRPC, what's your `sleep` implementation there? the default one provided by node is a promise, so you probably have to declare the function as `async` and call `await sleep(1000)` for this to work. – mrbm Jan 16 '20 at 17:05
  • @mrbm that's EXACTLY what it was. Very glad you pointed this out. I was just using a sleep function from another javascript project's utility folder - didn't happen to work in this case. Totally solved after taking your suggestion. – ThePartyTurtle Jan 16 '20 at 17:57
  • @mrbm If you post that comment as an answer I'll happily accept it. – ThePartyTurtle Jan 16 '20 at 18:18
  • 1
    I'm glad to help! – mrbm Jan 17 '20 at 18:13

1 Answers1

3

It could be unrelated to gRPC, but to the sleep implementation used there.

The default one provided by node is a promise, so for this to work you probably have to declare the function as async and call await sleep(1000);.

mrbm
  • 2,164
  • 12
  • 11