Ruby, Async and HTTP
The Async library for ruby is pure magic. Asynchronously running arbitrary ruby code, without having to deal with the pesky coloured functions of other languages, is beautiful and powerful.
I haven't explored the sister project, async-http, much at all until recently. I'm building a rails project which has both a web interface and an API. Posts to the API cause a cascade of model updates which trigger Turbo Streams refreshes in the browser.
A client gem makes the API calls. As they're all simple fire-and-forget POST
messages, they're ideal for wrapping in async. Something like this:
def post(document, to:)
Async do
internet = Async::HTTP::Internet.new
body = document.to_json
endpoint = to
internet.post(endpoint, headers, body)
ensure
internet.close
end
end
Don't do this
This worked really well until my web server decided to negotiate HTTP/2 connections and the client died after the first POST
.
warn: Async::HTTP::Client: connected to #<Addrinfo: [::1]:3000 TCP (localhost)>
| Waiting for Async::HTTP::Protocol::HTTP1 pool to drain: #<Async::Pool::Controller(1/∞) 1/1/1>
Async error message
I really was tearing my hair out and briefly considered sending POST
s with the venerable HTTParty wrapped in an async block (I'm going to gush again about no coloured functions❤️)
This is all I needed to do: it's sets up a background reader to process the async HTTP response! doh!
def post(document, to:)
Async do
internet = Async::HTTP::Internet.new
body = document.to_json
endpoint = to
Async do
internet.post(endpoint, headers, body)
end
ensure
internet.close
end
end
Do this instead
Member discussion