Skip to content

Conversation

@LaurentRDC
Copy link
Contributor

This is a cookbook recipe to serve infinite HTTP streams. There are a lot of subtleties in providing an HTTP infinite stream because data must be sent to the client on a regular basis.

@LaurentRDC LaurentRDC marked this pull request as ready for review October 26, 2025 00:25
@LaurentRDC
Copy link
Contributor Author

Looks like a new release of crypton-x509-store contains a breaking change, preventing the build. Unrelated to this PR

@LaurentRDC
Copy link
Contributor Author

LaurentRDC commented Oct 26, 2025

@tchoutri
Copy link
Contributor

@LaurentRDC The package's metadata seems to have been amended on Hackage. :)

@tchoutri tchoutri force-pushed the infinite-streams-recipe branch from 5cc3381 to 0772f4c Compare October 26, 2025 11:38
@LaurentRDC LaurentRDC force-pushed the infinite-streams-recipe branch from 0772f4c to 6643298 Compare October 26, 2025 14:29
@tchoutri
Copy link
Contributor

@LaurentRDC Thanks for the PR. I left some comments for clarification. :)

@LaurentRDC LaurentRDC force-pushed the infinite-streams-recipe branch from 6643298 to 6945b21 Compare October 27, 2025 23:46
@LaurentRDC
Copy link
Contributor Author

Thanks for your review!

While addressing your comments, I have also refactored the tricky logic that interleaves integers with KeepAlive messages to use withAsync. I find this more intuitive, and easier to explain! Let me know what you think.

@LaurentRDC LaurentRDC requested a review from tchoutri October 27, 2025 23:47
Comment on lines 245 to 246
go (SourceT.Error err) = error err
go (SourceT.Stop) = error "Unexpected stream end"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not seeing a "graceful" handling of stream completion in these two cases. This is purely due to my own ignorance as I don't do stream processing in my day-to-day job.

Would you advise that they both (Error & Stop) be handled in the same way (a log entry with a callstack, for instance), or should there be different "finaliser" code in one or the other?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cookbook is really concerned with infinite streams. As such, there should not be a need for graceful shutdown, as in, this part of the code is unreachable.

I have cleaned up cases, by having separate finalizers: a stream Error results in an exception being thrown, and a Stop results in pure (). Let me know what you think.

@LaurentRDC LaurentRDC force-pushed the infinite-streams-recipe branch from 6945b21 to 44aab7a Compare October 29, 2025 00:14
@tchoutri
Copy link
Contributor

@LaurentRDC Wonderful. One last question and I'll merge: What is the reasoning behind the use of throwIO in favour of error? Do you get nicer callstacks or something?

@LaurentRDC
Copy link
Contributor Author

LaurentRDC commented Oct 29, 2025

What is the reasoning behind the use of throwIO in favour of error? Do you get nicer callstacks or something?

There's no deep reason. I personally think of error as "quick-and-dirty", and throwIO as more proper.

@LaurentRDC LaurentRDC requested a review from tchoutri October 29, 2025 12:56
Copy link
Contributor

@tchoutri tchoutri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, let's go!

@tchoutri tchoutri merged commit ed1bf53 into haskell-servant:master Oct 29, 2025
9 checks passed
@LaurentRDC
Copy link
Contributor Author

Thanks for reviewing @tchoutri !

@tchoutri
Copy link
Contributor

@LaurentRDC It was also the opportunity to learn more. :) Hope to see more cookbooks from you! :)

@tchoutri
Copy link
Contributor

@LaurentRDC I came across this page that explains more why throwIO is better than error: https://gitlab.haskell.org/ghc/ghc/-/wikis/exceptions/precise-exceptions

@LaurentRDC
Copy link
Contributor Author

Very interesting! Thanks for sharing!
So basically, error is quick and dirty compared to throwIO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants