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
Improvements for using xml-conduit for streaming XML protocols #85
Conversation
-- this function doesn't support prettifying. Also it won't do certain other | ||
-- optimizations, like using self-closed tags. | ||
renderBuilderFlush :: Monad m => RenderSettings -> Conduit (Flush Event) m (Flush Builder) | ||
renderBuilderFlush settings@(RenderSettings { rsPretty = True }) = error "renderBuilderFlush: prettifying is not supported" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an inherent reason this isn't supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never mind, I read the comment. I see that there's a reason, I guess I'm just not following it. In any event, I think adding a comment explaining that rsPretty
is ignored in this function would be preferable to errorring out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I'm bad at comments and explanations -_-
It was made this way to guarantee that Flush would emit all piped data further, acting as a barrier. Consider this scenario: I first send Chunk EventBeginDocument{}
, then Chunk EventBeginElement{}
and then Flush
. At this point I expect that output would consist of prologue and an opening tag. But if something relies on peeking, it can't be done because we would need the next Chunk to get event out of it. Hence, disabled everything that relies on peeking. This actually happens in XMPP where I need to send an opening tag and then wait for the server to response before sending next messages.
On the other hand, while writing this I realized that it can actually be done if I would peek at the Flush stream directly and decide conservatively if Flush is encountered. For example, in the case of isClosed
I can just default it to False when that happens. This would get me a nice optimization, too (less text to send for self-closing tags). Stay tuned for an updated version of the patch!
I've pushed the second version of this patch -- now prettifying and emitting self-closed tags is supported. The code looks better IMO, too. |
Looks good, thanks! Can you add some Haddocks to the top of all the newly exported functions? |
Done for all |
LGTM, thanks! |
Thank you for review ^_^ |
This consists of two parts:
element{To,From}Events
which allow one to render streams from elements rather than complete documents. For example, I use this to implement an XMPP client which first sends opening<stream>
root element (manually encoded with[Event]
) and then lots of messages (Element
s) inside which are sent in real time via a conduit.renderBuilderFlush
which allows one to control where downstreambuilderToByteStringFlush
should flush message to the socket. This is required for streaming protocols where one is expected to send part of XML "document" (a "stanza" for XMPP) and then await for reply.