Tonic: Large packets (2GB) don't get sent

Created on 16 May 2020  路  6Comments  路  Source: hyperium/tonic

Bug Report

It takes Tonic approximately ~25 seconds to prepare a packet when it's 2GB in size, but ultimately it doesn't get received by the localhost server and the client just sits idle. Gave up after 5 minutes of waiting.

image

Minimal repro attached

tonic-repro.zip

bug crattonic

Most helpful comment

Yep, I just checked with logs turned on, the chunk is rejected for a wrong reason (woops). I'll file an issue on the h2 repo.

All 6 comments

@seanmonstar you may be interested

This will just be a collection of various worst-case scenarios again:

  • Reading big data chunks with some read_to_end() API will require those to be resized/reallocated each time until they had been read completely. On each resize you need to copy all already received data into the new segment. Assuming you ask for 1MB extra on each resize you need 2000 allocations, with 2000 * 1 GB byte copies on average.
  • Besides that some problems with tokios AsyncRead trait might lead to calling excessive extra initialization of target arrays with 0s on every read. Which could mean at some time you will write up to 2GB of 0s for every read() call.

Fixes:

  • Generally: Don't use gRPC for transferring big data chunks. Use streaming.
  • Implementation wise: Things which read bigger chunks of data should resize them upfront to the target size and don't do dynamic resizing.

Surely though; they should still arrive properly?

Yep, I just checked with logs turned on, the chunk is rejected for a wrong reason (woops). I'll file an issue on the h2 repo.

Sounds about right. Tonic doesn't do any sort of checking for that and delegates to h2.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

LucioFranco picture LucioFranco  路  5Comments

LucioFranco picture LucioFranco  路  6Comments

scottlamb picture scottlamb  路  5Comments

matthauck picture matthauck  路  6Comments

LucioFranco picture LucioFranco  路  6Comments