Persistent

Usually, single request calls close the connection afterwards. You can extend the lifetime of the connection(s) using .wrap, but that’s about it:

HTTPX.get("https://nghttp2.org")
#=> opens a secure connection to "nghttp2.org"
#=> sends request, gets response back"
#=> closes the connection

HTTPX.wrap do |session|
  session.get("https://nghttp2.org")
  # connection is still alive
end
# connection closed

With the :persistent plugin, connections will be kept open during the lifetime of the process:

session = HTTPX.plugin(:persistent)
session.get("https://nghttp2.org")
#=> opens a secure connection to "nghttp2.org"
#=> sends request, gets response back"

HTTPX.wrap do |sess|
  # will reuse the same connection
  sess.get("https://nghttp2.org")
  # connection is still alive
end
# connection still alive

Reconnections

If the connection goes down (because the peer closed it after a period of inactivity), the connection will be reopened and requests will be retried in the new connection:

session = HTTPX.plugin(:persistent)
session.get("https://google.com")
#... 5 mins have passed, and google shuts down the TCP socket ...
session.get("https://google.com")
# sending request in the connection fails
# new connection is created
# new request is sent, new connection kept alive

When you should use this

So why isn’t this turned on by default? Keeping connections alive for the duration of a process alocates resources indefinitely, and in some edge cases, you might hit limitations of your OS (such as EMFILE).

You should therefore use it:

  • If you’re connecting always to a known and bound set of origins;
  • If your process is long lived;

You’re not recommended to use it:

  • If the number of origins you’re connecting to is unbounded (example: web scraping/web crawler);
  • If your process is short lived;

Next: Stream