valyala/fasthttp

Blocking BodyStreamWriter

Open

#840 ouverte le 22 juin 2020

Voir sur GitHub
 (12 commentaires) (0 réactions) (0 assignés)Go (1 755 forks)batch import
bughelp wantedpending/development

Métriques du dépôt

Stars
 (21 741 stars)
Métriques de merge PR
 (Merge moyen 1j 11h) (34 PRs mergées en 30 j)

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!

Guide contributeur