Skip to content

Cleanup when responding to client close message #253

@ChickenProp

Description

@ChickenProp

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?)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions