Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support: sockets as flows with compatible poly variants #736

Open
cdaringe opened this issue Jun 2, 2024 · 1 comment
Open

Support: sockets as flows with compatible poly variants #736

cdaringe opened this issue Jun 2, 2024 · 1 comment

Comments

@cdaringe
Copy link

cdaringe commented Jun 2, 2024

Hey friends! Candidly, this is a support request for eio migration/upgrade. If you want me to go to S.O., that's fine.

Problem

I upgraded eio, and suffered some breaking changes, for which I cannot recover. I use ocaml so infrequently these days that I could use a bump handling the update gracefully

Context

I have two modules of interest:

  • server.ml, which creates sockets for udp sessions
  • road.ml, which stores a reference to those sockets

During migration, polymorphic variants are now all over socket and flow types.

Let's check it out:

217 |   let dispatchers_by_road_id = Hashtbl.create 10
            ^^^^^^^^^^^^^^^^^^^^^^
  The type of this value,
  (int, ([> `Generic ] as '_weak1) Eio.Net.stream_socket_ty Eio__.Flow.sink)
  Hashtbl.t, contains the non-generalizable type variable(s) '_weak1.

Dang, it used to be inferable. Ok, so what can I put in there now instead?

Well, the code that produces the socket handler (let socket = Eio.Net.datagram_socket ~sw net addr ) gives a 'tag datagram_socket_ty t, which is inferred to [> `Generic ] datagram_socket_ty t. Something tells me this may be too narrow of a type already? Unsure.

Let's try using that inferred by anyway to dodge the compilation error:

  let dispatchers_by_road_id: (int, [`Generic] Eio.Net.datagram_socket_ty Resource.t) Hashtbl.t = Hashtbl.create 10

Shoot, now downstream I get:

Type
  [ `Generic ] Net.datagram_socket_ty =
    [ `Close | `Datagram | `Platform of [ `Generic ] | `Shutdown | `Socket ]
is not compatible with type [> Eio__Flow.sink_ty ] = [> `Flow | `W ]

Which sure kinda makes sense... i'm just not clear from reading the docs and examples how to best express my types and interoperate between socket and flow primitives?

If you wanna see the actual code, this failure is present here: https://github.com/cdaringe/protohacks/tree/im-bad-at-ocaml-im-sorry and produces the errors discussed above.

No pressure to help 🤷, can't hurt to ask :)

@talex5
Copy link
Collaborator

talex5 commented Jun 14, 2024

The "non-generalizable type variable" happens in cases like this:

$ cat a.ml
let x = ref None

$ ocamlopt -c a.ml
File "a.ml", line 1, characters 4-5:
1 | let x = ref None
        ^
Error: The type of this expression, '_weak1 option ref,
       contains the non-generalizable type variable(s): '_weak1.
       (see manual section 6.1.2)

Giving it a concrete type is the solution, as you found.

The other problem looks like you're trying to use a datagram (message based) socket as a flow (byte-stream), which doesn't really make sense. For example, if you try to write "hello" to a flow and the kernel says it wrote 3 bytes then we do another call to send remaining the "lo" bit, but you don't want to do that with a datagram socket.

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

No branches or pull requests

2 participants