Skip to content
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

[RFC] Allow setting timeouts on HTTP::Server::Response #14799

Open
Blacksmoke16 opened this issue Jul 8, 2024 · 2 comments
Open

[RFC] Allow setting timeouts on HTTP::Server::Response #14799

Blacksmoke16 opened this issue Jul 8, 2024 · 2 comments

Comments

@Blacksmoke16
Copy link
Member

Creating this on behalf of @m-o-e related to a discussion on gitter.

A HTTP::Server::Response is backed by default via a Socket when using HTTP::Server. The proposed use case is making it easier to define an explicit timeout on the underlying response by providing a #write_timeout= method on the server response obj itself. The way they went about this was like ctx.response.output.as(HTTP::Server::Response::Output).@io.as(Socket).write_timeout = 1.second.

One potential problem with this is that there is no requirement that an http response is backed by a Socket. The setter could ensure the #output responds to :write_timeout=, and no-ops if it does not. Ideally there'd maybe be an interface for timeoutable IOs, but thats prob for another discussion. I also suggested it would be easier to do this at a reverse proxy level like nginx, but do agree that you shouldn't have to need to set one of those up just to do this.

Either way, wanted to at least get something created for posterity for future discussion.

@m-o-e
Copy link
Contributor

m-o-e commented Jul 8, 2024

require "http/server"

# 1. Run this server
#
# 2. In second terminal run:
#    curl -Nv http://localhost:9876
#
# 3. Hit ^Z to suspend the curl
#
# 4. Observe in first terminal what happens to the server.
#    WITHOUT timeout: Server blocks indefinitely
#    WITH timeout: <HTTP::Server::ClientError:Error while flushing data to the client>

server = HTTP::Server.new do |ctx|
  # Uncomment the following line to test the "WITH timeout" case
  # ctx.response.output.as(HTTP::Server::Response::Output).@io.as(Socket).write_timeout = 1.second

  loop do
    ctx.response.print("hello")
    puts Time.utc
  end
rescue ex : Exception
  p! ex
end

# Start the server
address = "127.0.0.1"
port = 9876
puts "Listening on http://#{address}:#{port}"
server.bind_tcp(address, port)
server.listen

@dsisnero
Copy link

I think we should abstract timeout and such further to cancellation tokens. Please read this article https://vorpus.org/blog/timeouts-and-cancellation-for-humans/ which explains the difference in detail.

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

No branches or pull requests

3 participants