-
Notifications
You must be signed in to change notification settings - Fork 38.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce token-based consumption of multipart requests in WebFlux #28006
Comments
As part of this effort, we would also deprecate the current streaming support in |
After considering the way (Reactor) Netty deals with multipart streaming, we have come up with an alternative to the token-based approach described above, so that headers and body contents are merged into one Part Data objectsIn this design, each part in a multipart HTTP message produces at least one For instance, a multipart message with a form field and a file will produce the following tokens:
|
The second approach with a unified However, I think there is a way to still have a composite approach with an outer The conditions for this composite approach to work is to maintain the following predicates true:
I agree that the composite approach implementation is more complex, and I am not sure it is always interesting to have an outer |
this is related with #27743 right ? |
This feature is now in There is no reference documentation as of yet, it will be written when the RC approaches, but for now there is a substantial amount of Javadoc on the main type: Note that I changed the name of this type from |
While the user might be able to limit their usage of operators on the
I will try to refactor the |
Would be great if you could provide a working example of this :) thx and great work ! |
This commit refactors the PartGenerator to use the newly introduced Token::isLast property. See gh-28006
There is some sample code available on the PartEvent Javadoc. |
In version 5.3, Spring Framework introduced the
DefaultPartHttpMessageReader
as a fully reactive way to handle multipart upload requests. One of the features of this message reader is streaming mode, where the contents of the uploaded parts is not stored in memory or on disk, but directly passed on to the subscriber (in the form of DataBuffers ). This feature is particularly useful for server proxies, where the controller passes on the data buffers to another service, for instance by usingWebClient
.However, there is a problem in the way streaming mode deals with back pressure. In streams produces by other
HttpMessageReader
s and codecs, there is a clear relationship between the requests made by the subscriber and the request made against the incoming buffer stream (for instance, theByteBufferDecoder
creates oneByteBuffer
for each incomingDataBuffer
). WhenDefaultPartHttpMessageReader
is used in streaming mode, there is no such relationship, because eachPart
produced can consists of multiple databuffers. Effectively, there are two kinds of back pressure in streaming mode:Part
elements, i.e. the 'outer' fluxDataBuffer
contents of each part, i.e. the 'inner' flux.There are several scenarios to consider:
flatMap
is used on thePart
stream?Though I am sure we can come up with answers to these questions, the fact remains that in streaming scenarios, representing multipart data as
Flux<Part>
where each part contains aFlux<DataBuffer>
has inherent difficulties with back pressure. Instead, we should introduce an alternative way to consume multipart data, a better fit for streaming scenarios.Part tokens
Instead
Part
elements, the multipart upload is represented by a stream of part tokens. Each part in the multipart request is represented by a header token that contains the part headers, followed by one or more body tokens with data buffers containing the part body. Subsequent parts will result in another header token, followed by more body tokens, and so on.For instance, a multipart message with a form field and a file will produce the following tokens:
Using part tokens, there is a direct relationship between back pressure of the the token subscriber and that of the buffer input. In the case of body tokens, this even is a 1-on-1 relationship.
For instance, here is a typical controller method that splits the tokens into multiples fluxes that start with a header token, so that each inner flux contains the tokens of one part. The headers from said token can then be used if necessary, and the remaining body tokens can be used as well.
The text was updated successfully, but these errors were encountered: