Skip to content

Use upstream net-http-persistent, connection_pool (un-vendored) - #345

Merged
chrisarcand merged 2 commits into
hashicorp:masterfrom
nevans:unvendor-gems
Dec 3, 2025
Merged

Use upstream net-http-persistent, connection_pool (un-vendored)#345
chrisarcand merged 2 commits into
hashicorp:masterfrom
nevans:unvendor-gems

Conversation

@nevans

@nevans nevans commented Feb 24, 2025

Copy link
Copy Markdown
Contributor

net-http-persistent and connection_pool were vendored, and have gotten very out-of-date. This resets to use the upstream gems.

connection-pool is upgraded from 2.2.0 to 2.4+:

  • 2.2.5 fixes argument forwarding for ruby 2.7+.
  • 2.4.0 automatically drops all connections after fork.

net-http-persistent is upgraded from 3.0.0 (forked) to 4.0.2+:

  • 4.0.2 fixes compatibility with connection-pool 2.4
  • 3.1.0 supports TLS min/max and IPv6 (also in vendored fork)
  • 3.1.0 fixes a memory leak in connection pooling.
  • Many many bugfixes
  • some vendored fork differences were removed:
    • use :name, :pool_size kwargs for .new

One change to the vendored fork was reimplemented: upstream does not support timeout kwarg for .new, nor does connection_pool expose an accessor for its timeout. So this code reaches into the pool and sets the @timeout ivar directly.

Additionally, all of the exceptions which net-http handles (in Net::HTTP#transport_request) are added to RESCUED_EXCEPTIONS. Net::HTTP uses these to determine whether the socket should be closed (and whether idempotent requests should be retried).

Please note: this incorporates #346, so CI can pass.

@nevans
nevans requested a review from a team as a code owner February 24, 2025 21:54
@hashicorp-cla-app

hashicorp-cla-app Bot commented Feb 24, 2025

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@nevans nevans changed the title Un-vendor gems: upgrade net-http-persistent and connection_pool Use upstream net-http-persistent and connection_pool (un-vendored) Feb 24, 2025
@nevans nevans changed the title Use upstream net-http-persistent and connection_pool (un-vendored) Use upstream net-http-persistent, connection_pool (un-vendored) Feb 24, 2025
@nevans nevans mentioned this pull request May 8, 2025
@nevans

nevans commented Nov 21, 2025

Copy link
Copy Markdown
Contributor Author

@chrisarcand @brandonc Sorry to ping you on this. I just noticed that vault-rails recently had its first update in a long time. And this gem is in serious need of maintenance, for compatibility with modern ruby versions.

Do you have any feedback on the approach I've used here? Is there some reason the vault gem needs to continue using vendored versions of these libraries? Because I can recreate this PR using the vendored approach, if necessary.

@chrisarcand

Copy link
Copy Markdown
Member

Ah thanks for the ping. We're in a period of ownership transition here at IBM/HashiCorp so indeed, sorry for the no response here, this definitely looks like it needs doing.

I'll get back to this by early next week and if you don't hear from me then, feel free to ping several times 😄

@nevans

nevans commented Nov 25, 2025

Copy link
Copy Markdown
Contributor Author

@chrisarcand ping 😉

Thanks for the update. Given that this is Thanksgiving week in the USA, you might not have time for it this week. But, you asked for a reminder so here it is! 🙂

For what it's worth, I've been running (in production) a branch that merges the following PRs:

I was originally running #329 because I was debugging an issue that was eventually fixed by this PR. The problem was that we had forking processes that connected in the parent process but didn't disconnect/reconnect in the child processes. The latest version of connection-pool gem handles forking reconnects automatically (unless you specifically opt-out).

The errors we got from the sharing connection between forked processes were that one process would read the responses to requests made by another process. Most of the time, that resulted in protocol errors, parse errors, or nil reference errors. But, as you can imagine, those weren't the only results. It could've been truly catastrophic (and when we first discovered the bug, before we put safeguards in place, it nearly was). So, IMO, this is a very high priority PR.

And yes, with my experience, I should've known (without being told) when we first added vault to our forking codebase that we'd need to handle disconnects on fork! But IMO, this should also be in the README, either as "You need to reconnect on fork" or as "This gem automatically reconnects on fork". (I can make a separate PR for that! 😉)

@chrisarcand

Copy link
Copy Markdown
Member

Thanks! Indeed I sorta forgot I was taking the whole week off for the US holiday ;)

I'm going to start with the base (#346) and then move to this - this looks real good though.

Securing some checkboxes to be able to get this stuff merged, thanks for your patience.

@nevans
nevans force-pushed the unvendor-gems branch 4 times, most recently from 0139d86 to 85abe54 Compare December 1, 2025 22:21
@chrisarcand
chrisarcand requested a review from a team as a code owner December 3, 2025 18:21

@chrisarcand chrisarcand left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

Comment thread lib/vault/client.rb

@nhp = PersistentHTTP.new("vault-ruby", nil, pool_size, pool_timeout)
@nhp = Net::HTTP::Persistent.new(name: "vault-ruby", pool_size:)
@nhp.pool.instance_variable_set(:@timeout, pool_timeout)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is definitely a little Hacky but but reasonable given that it doesn't appear there's any upstream method to set this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that really annoyed me too. But the main risk from this is timeouts not working correctly, and (IMO) that's still safer than not being able to get fixes from upstream.

@chrisarcand

Copy link
Copy Markdown
Member

Sigh. The merge commit screwed things up, I'll rebase this.

`net-http-persistent` and `connection_pool` were vendored, and have
gotten very out-of-date.  This resets to use the upstream gems.

`connection-pool` is upgraded from 2.2.0 to 2.4+:
* 2.2.5 fixes argument forwarding for ruby 2.7+.
* 2.4.0 automatically drops all connections after fork.

`net-http-persistent` is upgraded from 3.0.0 (forked) to 4.0.2+:
* 4.0.2 fixes compatibility with `connection-pool` 2.4
* 3.1.0 supports TLS min/max and IPv6 (also in vendored fork)
* 3.1.0 fixes a memory leak in connection pooling.
* some vendored fork differences were removed:
  * use :name, :pool_size kwargs for .new

One change to the vendored fork was reimplemented: upstream does _not_
support timeout kwarg for .new, nor does `connection_pool` expose an
accessor for its `timeout`.  So this code reaches into the pool and sets
the `@timeout` ivar directly.
These exceptions are copied from the list of exceptions which Net::HTTP
uses in `#transport_request` to determin whether the socket should be
closed (and retried, for idempotent requests).
@chrisarcand
chrisarcand merged commit 3b07590 into hashicorp:master Dec 3, 2025
18 checks passed
@nevans
nevans deleted the unvendor-gems branch December 5, 2025 19:04
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.

3 participants