Skip to content

withBuffer should kill the other thread when one completes #1

Description

@ocharles

withBuffer creates two threads - one to produce values and one to consume values. They communicate with a "seal" which starts empty, and when one thread finishes it signals that the work is done. The other thread notices the seal has been written to and stops what it is doing. However, this only works if the threads are blocked on activities relating to the basket. If they are actually blocked on some IO, they will never be terminated, and hence the whole withBuffer never terminates.

In my project, I have a producer that reads from a Socket, and the consumer reads Binary serialized values from connections to this socket:

withSocketValues
  :: (Binary a, Show a, MonadBase IO m, MonadMask m, MonadBaseControl IO m)
  => Socket -> (Stream (Of a) m () -> m r) -> m r
withSocketValues socket go =
  withBuffer unbounded receive (\basket -> withStreamBasket basket go <* liftBase (putStrLn "OK"))

  where
    receive basket =
      liftBase $
      forever $ do
        (client, _, _) <- accept socket
        forkIO $ writeStreamBasket (decoded (SBS.hGetContentsN 1 client)) basket

After all clients are done sending data, this won't terminate, because the receive action just gets stuck in accept.

I think withBuffer should be in charge of killing the reader or writer. Does this make sense?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions