-
Notifications
You must be signed in to change notification settings - Fork 273
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
Kylegoetz udp #4844
Kylegoetz udp #4844
Conversation
Hi @kylegoetz this is exciting! You could try try taking a look at @runarorama Could you take a look when you have a chance and weigh in on Kyle's Decisions / Tests / and @ChrisPenner @dolio Could you give a spot check as well? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll defer to Dan for calling conventions and Rúnar for interface design, so aside from that I'm not seeing any issues 👍🏼
@@ -81,9 +82,24 @@ import Network.Simple.TCP as SYS | |||
import Network.Socket as SYS | |||
( Socket, | |||
accept, | |||
socketPort, | |||
socketPort, PortNumber, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this eventually won't pass ormolu.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the workflows a bit to be more flexible, we'll see what happens.
Looks okay to me. I was a little skeptical about |
@aryairani I've pushed a A couple notes:
If I copy the
But in UCM I can
I don't know if the integration tests uses a pre-built UCM binary rather than my custom built one with the new UDP built-ins using
and Unison doesn't complain about these hashes when part of a scratch file and run as part of the |
@runarorama if Also, for all involved, if y'all want the interface to be different in some way, I can rewrite or add built-ins. I just tried to parallel the TCP terms/types as closely as possible while taking into account the different natures of UDP vs TCP (i.e., connection-less vs connection-present). |
I merged |
…goetz-udp # Conflicts: # parser-typechecker/src/Unison/Builtin.hs # parser-typechecker/src/Unison/Runtime/Builtin.hs
I haven't had a chance to try to reproduce the testing issue you mentioned, but I will try soon. |
No, it shouldn't be; if it is, then that's a bug in the CI setup. I think there might be one, I'm looking into it now. |
# Conflicts: # unison-src/transcripts-using-base/all-base-hashes.output.md # unison-src/transcripts/builtins-merge.output.md # unison-src/transcripts/emptyCodebase.output.md # unison-src/transcripts/merges.output.md # unison-src/transcripts/move-all.output.md # unison-src/transcripts/move-namespace.output.md # unison-src/transcripts/reflog.output.md # unison-src/transcripts/reset.output.md # unison-src/transcripts/squash.output.md # unison-src/transcripts/upgrade-happy-path.output.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good I think, will merge after one more test pass
Overview
There were no UDP types or terms. Now there are:
UDPSocket
ListenSocket
ClientSockAddr
IO.UDP.clientSocket.impl.v1 : Text -> Text -> Either Failure UDPSocket -- first param is hostname, second is port to connect to
IO.UDP.ClientSockAddr.toText.v1 :: ClientSockAddr -> Text
IO.UDP.UDPSocket.toText.impl.v1 :: UDPSocket -> Text
IO.UDP.UDPSocket.close.impl.v1 :: UDPSocket -> Either Failure ()
removed, see discussion belowIO.UDP.UDPSocket.socket.impl.v1 :: UDPSocket -> Socket
IO.UDP.serverSocket.impl.v1 :: Text -> Text -> Either Failure ListenSocket -- first param is the IP address, second is port
IO.UDP.ListenSocket.recvFrom.impl.v1 :: ListenSocket -> Either Failure (Bytes, ClientSockAddr)
IO.UDP.ListenSocket.sendTo.impl.v1 :: ListenSocket -> Bytes -> ClientSockAddr -> Either Failure ()
IO.UDP.ListenSocket.toText.impl.v1 :: ListenSocket -> Text
IO.UDP.ListenSocket.close.impl.v1 :: ListenSocket -> Either Failure ()
removed, see discussion belowIO.UDP.ListenSocket.socket.impl.v1 :: ListenSocket -> Socket
IO.UDP.UDPSocket.recv.impl.v1 :: UDPSocket -> Either Failure Bytes
IO.UDP.UDPSocket.send.impl.v1 :: UDPSocket -> Bytes -> Either Failure ()
Closes #4757
Implementation notes
Network.UDP
(Haskell) andracket/udp
(JIT) as dependencies.Interesting/controversial decisions
I chose to use the existing
Network.UDP
Haskell library because it appeared to be the easiest way to add UDP built-ins to Unison.The Haskell library tries to parallel a TCP connection-based library even though UDP is a connection-less protocol.
It might have been better to write more Haskell to create our own sockets configurable with UDP. Maybe a Unison Socket builtin that takes the same parameters as the Haskell Socket rather than a pre-baked TCP socket. Then implement everything at a lower-level and expose that to Unison, where Unison could have something like:
This might actually be a good improvement in the future because it's my understanding that you might need alternative configuration for the underlying Socket in order to support UDP-based multicast, e.g. Don't quote me on that.
Edit The JIT code mirrors the Haskell, which turns out to be similar under the hood.
Test coverage
There are tests found at
@unison/runtime-tests/@kylegoetz/udp
Loose ends
Maybe could use more testing to verify the Racket/JIT is actually spitting out
()
when it's supposed to (on send-y functions and close).One important thing to note is that when creating a client, the parameters are hostname and port, but when creating a server, the parameters are IP address and port. Because there is no
IPAddress
type inbase
currently, (contrast withHostName
), I've relied onreadMaybe
to cast theText
coming from Unison toMaybe IP
and then failing onNothing
but invoking the Haskell server creation onJust ip
.