mbonnin
09/07/2023, 10:58 AMbody(body: InputStream, length: Long?)
and not body(wire: OutputStream, length: Long?)
? My body produces bytes so I would expect to be given something I can write these bytes into (a socket?). I can buffer but it feels somewhat uneeded?fredrik.nordin
09/07/2023, 11:31 AMval bytes = ....
response.body(Body(bytes.asByteBuffer()))
fredrik.nordin
09/07/2023, 11:34 AMmbonnin
09/07/2023, 11:44 AMmbonnin
09/07/2023, 11:46 AMgenerateResponse(sink: OutputStream)
The response might be several GBs4nchez
09/07/2023, 11:55 AMBody
holds a reference to the actual content, and writing to the wire is the responsibility of the different client/server integrations.
@mbonnin I'd be curious to see an example of what you're trying to achieve. We've designed APIs to deal with large payloads (both as input and output, including streaming content to/from services like s3) without issues using the current model.mbonnin
09/07/2023, 11:58 AMwriting to the wire is the responsibility of the different client/server integrationsThis implies buffering, right?
I'd be curious to see an example of what you're trying to achieveIt's mostly curiosity at this point, I'm most likely going to return JSON payloads that are no more than a few 100kBs so certainly ok. But on the other hand if I can get a few % more requests/s by avoiding an extra memcpy, it's always less costs for me and better for the planet.
s4nchez
09/07/2023, 12:04 PMThis implies buffering, right?Yes, although the implementation may vary from client to client and from server to server. For instance, in
Jetty
we use a simple input.copyTo(output)
with the default JVM buffer size to transfer the content (see Http4kJakartaServletAdapter
)Jordan Stewart
09/07/2023, 9:57 PMbody(wire: (OutputStream) -> Unit, length: Long?)
right? (the output stream is provided by the underlying http server, and isn't available at the point you construct the response)
that would be more efficient, but it would also mean that the "it's just data" aspect would be lost (I mean, an InputStream already takes this away a little bit -- but you can at least buffer that if you're interested in reading it twice. A function could give you a different answer the second time . . .)
if you're not against starting a new thread you could do something like this which uses only a minimal buffer:
...
val in = PipedInputStream()
val out = PipedOutputStream(in)
thread {
out.use(generateResponse)
}
return Response(OK).body(StreamBody(input))
mbonnin
09/08/2023, 10:03 AMRight, good call 👍body(wire: (OutputStream) -> Unit, length: Long?)
mbonnin
09/08/2023, 10:08 AMif you're not against starting a new threadSounds like there's no way around threads. How would you collect them? Use daemon threads and just let them die? I guess I could also launch a global coroutine or so I guess
mbonnin
09/08/2023, 10:09 AMmbonnin
09/08/2023, 10:10 AMMikael Ståldal
09/08/2023, 3:33 PMJordan Stewart
09/09/2023, 6:30 PM