valyala/fasthttp

Blocking BodyStreamWriter

Open

#840 aberto em 22 de jun. de 2020

Ver no GitHub
 (12 comments) (0 reactions) (0 assignees)Go (1.755 forks)batch import
bughelp wantedpending/development

Métricas do repositório

Stars
 (21.741 stars)
Métricas de merge de PR
 (Mesclagem média 1d 11h) (34 fundiu PRs em 30d)

Description

Hi,

I've come across this issue when dealing with large files and slow clients. When using the example code below:

case "/test":
	{
	    ctx.SetBodyStreamWriter(func(w *bufio.Writer) {
		for i := 0; i < 3; i++ {
			mb := make([]byte, 10_000_000)
			rand.Read(mb)
			written, err := w.Write(mb)
			w.Flush()
			log.Printf("%d written %s", written, err)
	        	}
	           })
          }

(ignore the fact i'm allocating memory inside the loop, in production this is done using a pool, this is just purely to illustrate the problem)

In the example above if you download it with:

curl --limit 100K http://192.168.1.101:9876/test --output deleteme

all chunks get read into memory at once and then written to the user at the speed of 100K. This is fine for smaller files but if i increase the loop or concurrency then things start to blow up. I'd want to loop and read 10MB into memory, write it (however long it takes), read another 10MB, write, etc. as opposed to reading 30MB into memory all at once and writing it as slow as they dictate.

I've messed around with writing to the underlying Conn object, which does seem to block as you'd expect, but this doesn't really work well.

I'm just wondering what i'm doing wrong here, or if there is a way to block until each set of bytes has been truly written to the the user/client having to manually throttle requests by adding a sleep between loop iterations. Any help is massively appreciated as i've been banging my head against the wall all day trying to think of a proper way around this. Thanks!

Guia do colaborador