There seems to be a limit to the number of concurrent stream writers a script can have and it doesn’t fail gracefully in production (no error, no explanation).
I’m processing files from multiple resources and combining them into a single response:
The actual number of results is 40, but my stream processing in the client side JS is only able to received 21 of these results.
This happens consistently, even when I change the result types, order, etc…
My only conclusion is that I’m hitting some upper bound of some limit in Workers that’s causing the writer to stop accepting the pipeTo requests, the script is hanging and chrome is indicating that the response has not finished.
Extremely curious if anyone can shed some light on this situation…
for (let i = 0, len = results.length; i < len; ++i) {
key = `https://${bucket}.s3.amazonaws.com/${results[i].data}`
//cache or not?
let res = await cache.match(key)
let bodies = []
if (res) {
bodies = [res.body]
} else {
// console.log('request', i, Date.now() - t)
res = await global.AWS.fetch(key)
// console.log('response', i, Date.now() - t)
bodies = res.body.tee()
res = new Response(bodies[1], res)
res.headers.append('Cache-Control', 'max-age=' + global.DATA_TIMEOUT)
e.waitUntil(cache.put(key, res.clone()))
}
// const len = parseInt(res.headers.get('content-length'))
// streamed += len
// console.log('streamed', streamed)
length = res.headers.get('content-length').padStart(PADLEN, '0')
writer = writable.getWriter()
await writer.write(encoder.encode(length))
writer.releaseLock()
await bodies[0].pipeTo(writable, {preventClose: (i+1) !== results.length})
}
Your current method used in the wrong hands seems like it would be an excellent DDoS attack vector. I’m sure there is some limit to the maximum number of concurrent streams for precisely that reason. Assembly of a webpage using subatomic particles in an argon matrix seems like an interesting approach.
Was there an answer to my question or any helpful information in that response? I may have missed it.
I don’t believe I’m doing anything out of the ordinary, composing a response from multiple inputs seems like a strong use case for workers. In fact I modeled this after an example from @harris on GitHub.
Also if you notice, the loop is bounded to the length of my result set and each fetch is done sequentially waiting for the previous response. Not sure how a DDOS vector is remotely relevant here.