fs2 icon indicating copy to clipboard operation
fs2 copied to clipboard

Improve unix sockets support

Open mpilquist opened this issue 8 months ago • 2 comments

While adding support for connecting to Postgres via unix sockets to Skunk, I've come up with a few improvements we should make to fs2:

  • Add support for socket options to unix sockets
  • Support reading socket options from socket
  • Unify client connection API

Add support for socket options to unix sockets

Unix sockets support socket options but the client and server methods on UnixSockets don't currently accept an options list. Both methods should be updated to take a new param options: List[SocketOption] = Nil like the equivalent operations in SocketGroup.

Support reading socket options from socket

There's currently no way to programmatically get the value of a specific socket option. This is a significant gap for unix sockets where the SO_PEERCRED option is set by the kernel and may be queried by the application. We should add a getOption method to Socket and implement for all socket types and platforms.

Unify client connection API

Currently, if an application wants to support connecting via both TCP and unix sockets, the app has to call SocketGroup#client for TCP, supplying a host and port, and UnixSockets#client for unix domain sockets, supplying a path. The former is typically accessed by the Network[F] capability while the latter via UnixSockets[F] capability.

Instead, we should:

  • roll UnixSockets in to Network, throwing an unsupported operation on platforms without support
  • consider creation of a unified client api like Network[F].clientFromSpec(SocketClientSpec.tcp(hostAndPort)) where SocketClientSpec is a builder that supports full configuration of both TCP and unix sockets.

We should consider https://github.com/Comcast/ip4s/issues/466 here, though I'm not sure we should add support in ip4s after all. UnixSocketAddress should really wrap a Path, which is available in fs2.io.file. Furthermore, the params needed to open a client socket differ from the params needed to open a server socket -- a TCP client socket needs a SocketAddress[Host] whereas a server socket needs (Option[Host], Option[Port]). FS2 is in a better position to provide an abstraction here than ip4s.

mpilquist avatar Apr 07 '25 12:04 mpilquist

UnixSocketAddress should really wrap a Path, which is available in fs2.io.file

Ideally, yes, but a Path is basically just a String. I think that would be fine.

whereas a server socket needs (Option[Host], Option[Port])

I wonder if the None cases can be represented as a SocketAddress[Host] where the host is the wildcard address and the port is zero.

FS2 is in a better position to provide an abstraction here than ip4s.

I think I am still of the opinion that we should unify. This matches how the APIs are exposed in the JDK/Node.js/POSIX and should make it easier to support unix sockets without having to directly code for that feature in Ember/Skunk.

armanbilge avatar Apr 07 '25 17:04 armanbilge

I wonder if the None cases can be represented as a SocketAddress[Host] where the host is the wildcard address and the port is zero.

Good idea. I opened https://github.com/Comcast/ip4s/pull/648 for that. Note we'll need to encode the unix sockets deleteIfExists and deleteOnClose params as fs2 proprietary socket options with this approach.

mpilquist avatar Apr 07 '25 22:04 mpilquist