Skip to content

docs: Correct the socket_factory open() signature - #472

Draft
kinyoklion wants to merge 1 commit into
mainfrom
rlamb/sdk-3369/socket-factory-docs
Draft

kinyoklion wants to merge 1 commit into
mainfrom
rlamb/sdk-3369/socket-factory-docs

Conversation

@kinyoklion

Copy link
Copy Markdown
Member

Requirements

  • I have added test coverage for new or changed functionality
  • I have followed the repository's pull request submission guidelines
  • I have validated my changes against all supported platform versions

Related issues

SDK-3369

Describe the solution you've provided

Config#socket_factory was documented as requiring open(uri, timeout). The SDK passes the factory to http.rb as socket_class, and http.rb calls it as socket_class.open(host, port). That is true on every http.rb version the gemspec allows (>= 4.4.0, < 7.0.0), and has been since the option was added in 6.0.0.

A factory written to the documented signature gets a host name where it expects a URI, and a port where it expects a timeout. Depending on how it is written, it either:

  • raises NoMethodError on uri.host; or
  • takes its port from somewhere else and connects to the wrong place.

The second case is quiet: in a local check, events went to whatever server was on the factory's own port, and the SDK reported the send as successful.

Changes:

  • Config#socket_factory docs now:
    • give the real signature, open(host, port);
    • say those are the host and port to connect to, or the proxy's when a proxy is configured;
    • say the SDK performs TLS over the returned stream, so the stream must not already be encrypted;
    • say the SDK's connect timeout applies to the call. http.rb wraps the call in Timeout.timeout in 4.4.1, 5.3.1 and 6.0.4.
  • New note on FDv2 data sources: data sources created with the LaunchDarkly::DataSystem builders don't use Config#socket_factory. Each builder has its own socket_factory, and build_http_config only reads that.
  • DataSourceBuilderCommon#socket_factory docs: give the signature and point to Config#socket_factory.
  • Spec helper SocketFactoryFromHash: it declared open(uri, timeout) and ignored its second argument, mapping host names to ports. It now maps host names to addresses and connects to the port it is given. The two specs that use it put the server port in the URI, so they depend on the port argument.

Describe alternatives you've considered

Making the FDv2 builders fall back to Config#socket_factory. That's a behavior change, so I left it out of this docs fix.

Additional context

Testing:

  • spec/impl/event_sender_spec.rb and spec/ldclient_end_to_end_spec.rb pass on Ruby 3.2.3 with http.rb 6.0.4.
  • With the helper changed to ignore the port it's given:
    • the event sender spec fails;
    • the end-to-end spec never completes, because it waits for an events request with no timeout.
  • The full suite gave 1241 examples with 1 failure: can be automatically loaded by Bundler.require. That's local only: its inline Gemfile resolves against system gems, which here lack aws-sdk-dynamodb.
  • Rubocop is clean on the changed files, and YARD resolves the new links.

Follow-up: ld-eventsource has the same open(uri, timeout) wording (lib/ld-eventsource/client.rb:98).

The socket_factory docs said the factory must provide open(uri, timeout).
The SDK hands the factory to http.rb as its socket class, and http.rb has
always called it as open(host, port): the host and port to connect to, or
the proxy's when a proxy is configured. A factory written to the documented
signature would get a host name where it expected a URI and a port where it
expected a timeout.

Document the real signature, that the SDK performs TLS over the returned
stream, and that the connect timeout applies to the call. Also note that
data sources built with the DataSystem builders use their own
socket_factory, not Config#socket_factory.

The spec helper SocketFactoryFromHash had the same misleading parameter
names and ignored the port it was given. It now maps host names to
addresses and connects to the port the HTTP client passes in, so the specs
that use it depend on that argument.

This branch has not been deployed

No deployments
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.

1 participant