Skip to content

Let's remove the extra info inside stream message #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
windmemory opened this issue Oct 20, 2020 · 3 comments
Closed

Let's remove the extra info inside stream message #94

windmemory opened this issue Oct 20, 2020 · 3 comments
Labels
enhancement New feature or request

Comments

@windmemory
Copy link
Member

After significant amount of investigation on [how to send FileBox name with stream message], I finally figured out the solution, which does not require any extra info in the request or response messages.

Example

Server

messageFileStream: async (call) => {
  // Get some arguments from the request
  const id = call.request.getId()
  // Get the stream from FileBox
  const fileBox = FileBox.fromFile(`${__dirname}/test.json`)
  const stream = await fileBox.toStream()
  // Create a shared response to use in stream
  const response = new MessageFileStreamResponse()
  response.setName(fileBox.name)
  // Create a metadata to store the extra info and send it to client
  const metaData = new grpc.Metadata()
  metaData.add('fileName', fileBox.name)
  call.sendMetadata(metaData)

  stream.on('data', (data: Buffer) => {
    response.setData(data)
    call.write(response)
  }).on('end', () => {
    call.end()
  })
},

Client

public async makeCallStream (i: number) {
  // construct a request with parameters
  const request = new MessageFileStreamRequest()
  request.setId(i.toString())
  // make the call to the server and get the stream response
  const stream = this.grpcClient.messageFileStream(request)
  // read the metadata and get the extra info from it
  const fileName = await new Promise<string>((resolve, reject) => {
    stream.once('metadata', (metaData: grpc.Metadata) => {
      const nameValues = metaData.get(FILE_BOX_NAME_METADATA_KEY)
      resolve(nameValues[0].toString())
    })
  })

  const outputStream = new PassThrough()
  // read data from the stream
  stream.on('data', (response: MessageFileStreamResponse) => {
    oStream.write(response.getData())
  }).on('end', () => {
    oStream.end()
  })

  const fileBox = FileBox.fromStream(outputStream, fileName)
  return fileBox
}

So with this design, we don't need extra attributes that we added onto MessageImageStreamResponse, MessageFileStreamResponse and MessageSendFileStreamRequest , to make the proto clear, let's remove these attributes.

@windmemory windmemory mentioned this issue Oct 20, 2020
@windmemory
Copy link
Member Author

I just realized that when we want to send FileBox via grpc, the message should always be the same, so let's use a common message definition for the message that is actually a FileBox.

@huan
Copy link
Member

huan commented Oct 20, 2020

Thanks for make the code clean!

To make our design more clean, I'd like to say that what we are sending and receiving is a standard nodejs ReadableStream.

So I'm thinking about to rename the file box related named to just steam related, for example, data chunks.

@huan
Copy link
Member

huan commented Oct 26, 2020

Close this issue because this problem has been solved.

Thanks for creating this issue to explain the potential solution, it's very valuable!

@huan huan closed this as completed Oct 26, 2020
@huan huan added the enhancement New feature or request label Oct 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants