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

Cleanup when responding to client close message #253

Open
ChickenProp opened this issue Sep 2, 2024 · 0 comments
Open

Cleanup when responding to client close message #253

ChickenProp opened this issue Sep 2, 2024 · 0 comments

Comments

@ChickenProp
Copy link

Suppose I have a server that can both receive messages from the client and push messages unprompted. My sense is that the most natural way to write it is

  • Fork a thread (push-thread) for pushing that calls sendTextData or similar.
  • Have the main thread (pull-thread) calling receiveDataMessage or similar.
  • In pull-thread, catch CloseRequest and use it to kill push-thread.

But that's vulnerable to race conditions, because (afaict) it's possible for push-thread to try to send data in between pull-thread completing a close handshake and killing push-thread.

As-is, I can think of two ways around this.

  1. Don't use receiveDataMessage. Just use receive and handle control messages manually.
  2. conn' = conn { connectionWrite = onClose conn.connectionWrite act } where onClose oldWrite act msgs checks if any of the msgs is a Close and calls act if so; then regardless it passes them all on to oldWrite.

I don't love either of these. As an alternative, can we have a hook intended for this use case, something like

data CloseInitiatedBy = CloseInitiatedByUs | CloseInitiatedByThem
connectionOnClose :: CloseInitiatedBy -> IO ()

that gets called immediately before we send a close message?

(Though I think figuring out who initiated isn't possible right now... we'd could try something like connectionReceivedClose :: IORef Bool, but that could theoretically fail if both sides try to initiate around the same time. But that situation is already awkward because you might try to send two Close requests and one of them will throw an error. So I dunno, maybe it's fine? Or just not having CloseInitiatedBy in the hook and tell the user they need to figure this out if necessary?)

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

1 participant