Multicast receiver thread fails to receive last few messages
I am trying to send multicast messages from one thread, and receive them on another. The sending thread reads lines from a file and sends them. However, the receiving thread does not receive all the messages - it seems to miss the last 10 message or so. If I run other programs to listen for the multicast message, they receive them fine. So I think the issue is something to do with receiving, not sending. I keep the program alive with a threadDelay, so it shouldn't be halting prematurely. If I add a small delay after each send, it works fine. And if I make the input file smaller, it works fine. On the provided data file, on my system (64-bit Ubuntu, GHC 7.8.2), the receiver fails to receive lines 125-140. Compiled with no optimizations. Thanks for any help! The relevant code snippets are below, and the sample data file and full program are attached. -- Loop to receive all the packets let receiveMulticast = do (msg, _) <- recvFrom recvSock 32628 putStrLn . BS.unpack $ BS.take 100 msg receiveMulticast _ <- forkIO receiveMulticast -- Send every line from a file as multicast message inputFile <- openFile "data" ReadMode fileLines <- BS.lines <$> BS.hGetContents inputFile let sendMulticast msg = do sendTo sendSock msg addr -- Receiver FAILS to receive last few messages unless this -- thread delay exists... why?! -- threadDelay (1) mapM_ sendMulticast fileLines hClose inputFile threadDelay (1000*1000*1000) -- Delay for 1000 seconds
I would try forking your sending thread, too, rather than using the main thread for sending. Alternatively, use the main thread for receiving and fork your sending thread. – Kyle Marek-Spartz On Sep 23, 2014, 10:14:09 AM, Ben Gunton <ben.gunton@gmail.com> wrote: I am trying to send multicast messages from one thread, and receive them on another. The sending thread reads lines from a file and sends them. However, the receiving thread does not receive all the messages - it seems to miss the last 10 message or so. If I run other programs to listen for the multicast message, they receive them fine. So I think the issue is something to do with receiving, not sending. I keep the program alive with a threadDelay, so it shouldn't be halting prematurely. If I add a small delay after each send, it works fine. And if I make the input file smaller, it works fine. On the provided data file, on my system (64-bit Ubuntu, GHC 7.8.2), the receiver fails to receive lines 125-140. Compiled with no optimizations. Thanks for any help! The relevant code snippets are below, and the sample data file and full program are attached. -- Loop to receive all the packets let receiveMulticast = do (msg, _) <- recvFrom recvSock 32628 putStrLn . BS.unpack $ BS.take 100 msg receiveMulticast _ <- forkIO receiveMulticast -- Send every line from a file as multicast message inputFile <- openFile "data" ReadMode fileLines <- BS.lines <$> BS.hGetContents inputFile let sendMulticast msg = do sendTo sendSock msg addr -- Receiver FAILS to receive last few messages unless this -- thread delay exists... why?! -- threadDelay (1) mapM_ sendMulticast fileLines hClose inputFile threadDelay (1000*1000*1000) -- Delay for 1000 seconds - data, 71 KB - Main.hs, 2.2 KB _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Thanks Kyle. Tried forking both (http://lpaste.net/111477), and also receiving from the main thread while forking the sending, and the results were the same... still not receiving the last bunch of lines. On Tue, Sep 23, 2014 at 9:46 AM, Kyle Marek-Spartz < kyle.marek.spartz@gmail.com> wrote:
I would try forking your sending thread, too, rather than using the main thread for sending. Alternatively, use the main thread for receiving and fork your sending thread.
– Kyle Marek-Spartz
On Sep 23, 2014, 10:14:09 AM, Ben Gunton <ben.gunton@gmail.com> wrote: ------------------------------ I am trying to send multicast messages from one thread, and receive them on another. The sending thread reads lines from a file and sends them. However, the receiving thread does not receive all the messages - it seems to miss the last 10 message or so. If I run other programs to listen for the multicast message, they receive them fine. So I think the issue is something to do with receiving, not sending. I keep the program alive with a threadDelay, so it shouldn't be halting prematurely. If I add a small delay after each send, it works fine. And if I make the input file smaller, it works fine.
On the provided data file, on my system (64-bit Ubuntu, GHC 7.8.2), the receiver fails to receive lines 125-140. Compiled with no optimizations.
Thanks for any help!
The relevant code snippets are below, and the sample data file and full program are attached.
-- Loop to receive all the packets let receiveMulticast = do (msg, _) <- recvFrom recvSock 32628 putStrLn . BS.unpack $ BS.take 100 msg receiveMulticast _ <- forkIO receiveMulticast
-- Send every line from a file as multicast message inputFile <- openFile "data" ReadMode fileLines <- BS.lines <$> BS.hGetContents inputFile let sendMulticast msg = do sendTo sendSock msg addr -- Receiver FAILS to receive last few messages unless this -- thread delay exists... why?! -- threadDelay (1) mapM_ sendMulticast fileLines hClose inputFile
threadDelay (1000*1000*1000) -- Delay for 1000 seconds ------------------------------ - data, 71 KB - Main.hs, 2.2 KB _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
I think the problem here is that the receiver thread never gets a chance to run. Because the send loop doesn't perform any allocations and the GHC scheduler only switches threads when allocations occur, the receiver thread never runs and thus the packets just get queued up (and after a certain amount of data, the queue is full so packets are dropped). The fix is to explicitly `yield` to the other thread, so it gets a chance to run too: import Control.Concurrent (yield) ... let sendMulticast msg = do sendTo sendSock msg addr yield The `threadDelay` call had the same effect as the yield. This also explains why the file size matters. -- Benno 2014-09-23 17:58 GMT+02:00 Ben Gunton <ben.gunton@gmail.com>:
Thanks Kyle. Tried forking both (http://lpaste.net/111477), and also receiving from the main thread while forking the sending, and the results were the same... still not receiving the last bunch of lines.
On Tue, Sep 23, 2014 at 9:46 AM, Kyle Marek-Spartz < kyle.marek.spartz@gmail.com> wrote:
I would try forking your sending thread, too, rather than using the main thread for sending. Alternatively, use the main thread for receiving and fork your sending thread.
– Kyle Marek-Spartz
On Sep 23, 2014, 10:14:09 AM, Ben Gunton <ben.gunton@gmail.com> wrote: ------------------------------ I am trying to send multicast messages from one thread, and receive them on another. The sending thread reads lines from a file and sends them. However, the receiving thread does not receive all the messages - it seems to miss the last 10 message or so. If I run other programs to listen for the multicast message, they receive them fine. So I think the issue is something to do with receiving, not sending. I keep the program alive with a threadDelay, so it shouldn't be halting prematurely. If I add a small delay after each send, it works fine. And if I make the input file smaller, it works fine.
On the provided data file, on my system (64-bit Ubuntu, GHC 7.8.2), the receiver fails to receive lines 125-140. Compiled with no optimizations.
Thanks for any help!
The relevant code snippets are below, and the sample data file and full program are attached.
-- Loop to receive all the packets let receiveMulticast = do (msg, _) <- recvFrom recvSock 32628 putStrLn . BS.unpack $ BS.take 100 msg receiveMulticast _ <- forkIO receiveMulticast
-- Send every line from a file as multicast message inputFile <- openFile "data" ReadMode fileLines <- BS.lines <$> BS.hGetContents inputFile let sendMulticast msg = do sendTo sendSock msg addr -- Receiver FAILS to receive last few messages unless this -- thread delay exists... why?! -- threadDelay (1) mapM_ sendMulticast fileLines hClose inputFile
threadDelay (1000*1000*1000) -- Delay for 1000 seconds ------------------------------ - data, 71 KB - Main.hs, 2.2 KB _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Since this is UDP, you may be overflowing your device queue. Linux helpfully won't return ENOBUFS in this case but will instead just drop the packet on the floor. The threadDelay fixes this by yielding the processor so that the consumer thread can dequeue packets. G On Tue, Sep 23, 2014 at 8:14 AM, Ben Gunton <ben.gunton@gmail.com> wrote:
I am trying to send multicast messages from one thread, and receive them on another. The sending thread reads lines from a file and sends them. However, the receiving thread does not receive all the messages - it seems to miss the last 10 message or so. If I run other programs to listen for the multicast message, they receive them fine. So I think the issue is something to do with receiving, not sending. I keep the program alive with a threadDelay, so it shouldn't be halting prematurely. If I add a small delay after each send, it works fine. And if I make the input file smaller, it works fine.
On the provided data file, on my system (64-bit Ubuntu, GHC 7.8.2), the receiver fails to receive lines 125-140. Compiled with no optimizations.
Thanks for any help!
The relevant code snippets are below, and the sample data file and full program are attached.
-- Loop to receive all the packets let receiveMulticast = do (msg, _) <- recvFrom recvSock 32628 putStrLn . BS.unpack $ BS.take 100 msg receiveMulticast _ <- forkIO receiveMulticast
-- Send every line from a file as multicast message inputFile <- openFile "data" ReadMode fileLines <- BS.lines <$> BS.hGetContents inputFile let sendMulticast msg = do sendTo sendSock msg addr -- Receiver FAILS to receive last few messages unless this -- thread delay exists... why?! -- threadDelay (1) mapM_ sendMulticast fileLines hClose inputFile
threadDelay (1000*1000*1000) -- Delay for 1000 seconds
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Gregory Collins <greg@gregorycollins.net>
Indeed, this was the issue. Took Benno's advice and added a yield, and it works as I hoped it would. Thanks! On Tue, Sep 23, 2014 at 10:46 AM, Gregory Collins <greg@gregorycollins.net> wrote:
Since this is UDP, you may be overflowing your device queue. Linux helpfully won't return ENOBUFS in this case but will instead just drop the packet on the floor. The threadDelay fixes this by yielding the processor so that the consumer thread can dequeue packets.
G
On Tue, Sep 23, 2014 at 8:14 AM, Ben Gunton <ben.gunton@gmail.com> wrote:
I am trying to send multicast messages from one thread, and receive them on another. The sending thread reads lines from a file and sends them. However, the receiving thread does not receive all the messages - it seems to miss the last 10 message or so. If I run other programs to listen for the multicast message, they receive them fine. So I think the issue is something to do with receiving, not sending. I keep the program alive with a threadDelay, so it shouldn't be halting prematurely. If I add a small delay after each send, it works fine. And if I make the input file smaller, it works fine.
On the provided data file, on my system (64-bit Ubuntu, GHC 7.8.2), the receiver fails to receive lines 125-140. Compiled with no optimizations.
Thanks for any help!
The relevant code snippets are below, and the sample data file and full program are attached.
-- Loop to receive all the packets let receiveMulticast = do (msg, _) <- recvFrom recvSock 32628 putStrLn . BS.unpack $ BS.take 100 msg receiveMulticast _ <- forkIO receiveMulticast
-- Send every line from a file as multicast message inputFile <- openFile "data" ReadMode fileLines <- BS.lines <$> BS.hGetContents inputFile let sendMulticast msg = do sendTo sendSock msg addr -- Receiver FAILS to receive last few messages unless this -- thread delay exists... why?! -- threadDelay (1) mapM_ sendMulticast fileLines hClose inputFile
threadDelay (1000*1000*1000) -- Delay for 1000 seconds
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Gregory Collins <greg@gregorycollins.net>
altenratively, you can compile your module with -fno-omit-yields, which adds a yield to no allocation loops On Tue, Sep 23, 2014 at 2:26 PM, Ben Gunton <ben.gunton@gmail.com> wrote:
Indeed, this was the issue. Took Benno's advice and added a yield, and it works as I hoped it would. Thanks!
On Tue, Sep 23, 2014 at 10:46 AM, Gregory Collins <greg@gregorycollins.net
wrote:
Since this is UDP, you may be overflowing your device queue. Linux helpfully won't return ENOBUFS in this case but will instead just drop the packet on the floor. The threadDelay fixes this by yielding the processor so that the consumer thread can dequeue packets.
G
On Tue, Sep 23, 2014 at 8:14 AM, Ben Gunton <ben.gunton@gmail.com> wrote:
I am trying to send multicast messages from one thread, and receive them on another. The sending thread reads lines from a file and sends them. However, the receiving thread does not receive all the messages - it seems to miss the last 10 message or so. If I run other programs to listen for the multicast message, they receive them fine. So I think the issue is something to do with receiving, not sending. I keep the program alive with a threadDelay, so it shouldn't be halting prematurely. If I add a small delay after each send, it works fine. And if I make the input file smaller, it works fine.
On the provided data file, on my system (64-bit Ubuntu, GHC 7.8.2), the receiver fails to receive lines 125-140. Compiled with no optimizations.
Thanks for any help!
The relevant code snippets are below, and the sample data file and full program are attached.
-- Loop to receive all the packets let receiveMulticast = do (msg, _) <- recvFrom recvSock 32628 putStrLn . BS.unpack $ BS.take 100 msg receiveMulticast _ <- forkIO receiveMulticast
-- Send every line from a file as multicast message inputFile <- openFile "data" ReadMode fileLines <- BS.lines <$> BS.hGetContents inputFile let sendMulticast msg = do sendTo sendSock msg addr -- Receiver FAILS to receive last few messages unless this -- thread delay exists... why?! -- threadDelay (1) mapM_ sendMulticast fileLines hClose inputFile
threadDelay (1000*1000*1000) -- Delay for 1000 seconds
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Gregory Collins <greg@gregorycollins.net>
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (5)
-
Ben Gunton -
Benno Fünfstück -
Carter Schonwald -
Gregory Collins -
Kyle Marek-Spartz