sender :: Int -> MVar Int -> Chan Genome -> Chan Genome -> Socket -> IO ()
sender ntodo ndone todo done sock0 = withSocketsDo $ loop sock0
  where
    loop :: Socket -> IO ()
    loop sock = do
      (sck,_) <- accept sock
      infoM rootLoggerName "Connection accepted!"
      sHandle <- socketToHandle sck ReadWriteMode
      _ <- forkIO $ runLoop sHandle
      isDone <- (== ntodo) <$> readMVar ndone
      unless isDone (loop sock)
    runLoop :: Handle -> IO ()
    runLoop sHandle = do
      isDone <- (== ntodo) <$> readMVar ndone
      unless isDone $ do
        g <- readChan todo
        result <- try $ sendGenome sHandle g
        case result :: Either SomeException Genome of
          Right g' -> writeChan done g' >>
                      incMVar ndone >>
                      runLoop sHandle
          Left _ -> writeChan todo g >>
                    runLoop sHandle
sender :: Int -> MVar Int -> Chan Genome -> Chan Genome -> Socket -> IO ()
sender ntodo ndone todo done sock0 = withSocketsDo $ loop sock0
  where
    loop :: Socket -> IO ()
    loop sock = do
      (sck,_) <- accept sock
      infoM rootLoggerName "Connection accepted!"
      sHandle <- socketToHandle sck ReadWriteMode
      _ <- forkIO $ runLoop sHandle
      isDone <- (== ntodo) <$> readMVar ndone
      unless isDone (loop sock)
    runLoop :: Handle -> IO ()
    runLoop sHandle = do
      isDone <- (== ntodo) <$> readMVar ndone
      unless isDone $ do
        g <- readChan todo
        result <- try $ sendGenome sHandle g
        case result :: Either SomeException Genome of
          Right g' -> writeChan done g' >>
                      incMVar ndone >>
                      runLoop sHandle
          Left _ -> writeChan todo g >>
                    runLoop sHandle
sender ntodo ndone todo done sock0 = withSocketsDo $ loop sock0
  where
    loop :: Socket -> IO ()
    loop sock = do
      (sck,_) <- accept sock
      infoM rootLoggerName "Connection accepted!"
      sHandle <- socketToHandle sck ReadWriteMode
      _ <- forkIO $ runLoop sHandle
      isDone <- (== ntodo) <$> readMVar ndone
      unless isDone (loop sock)
    runLoop :: Handle -> IO ()
    runLoop sHandle = do
      isDone <- (== ntodo) <$> readMVar ndone
      unless isDone $ do
        g <- readChan todo
        result <- try $ sendGenome sHandle g
        case result :: Either SomeException Genome of
          Right g' -> writeChan done g' >>
                      incMVar ndone >>
                      runLoop sHandle
          Left _ -> writeChan todo g >>
                    runLoop sHandle