resolvServ
  :: HasLogFunc e
  => TVar (Maybe [Turf])
  -> (SockAddr -> ByteString -> IO ())
  -> (Text -> RIO e ())
  -> RIO e ResolvServ
resolvServ vTurfs send stderr = do
  vGala <- newTVarIO (mempty :: Map Galaxy (Async (), TQueue ByteString))
  vDead <- newTVarIO False
  envir <- ask

  let spawnWorker :: Galaxy -> IO (Async (), TQueue ByteString)
      spawnWorker gal = runRIO envir $ do
        que <- newTQueueIO
        las <- newTVarIO (Time.unixEpoch, Nothing)
        tid <- resolvWorker gal vTurfs las (readTQueue que) send stderr
        pure (tid, que)

  let getWorker :: Galaxy -> IO (Async (), TQueue ByteString)
      getWorker gal = do
        (fmap (lookup gal) $ atomically $ readTVar vGala) >>= \case
          Just (tid, que) -> do
            pure (tid, que)
          Nothing -> do
            (tid, que) <- spawnWorker gal
            atomically $ modifyTVar' vGala (M.insert gal (tid, que))
            pure (tid, que)

  let doSend :: Galaxy -> ByteString -> IO ()
      doSend gal byt = do
        dead <- atomically (readTVar vDead)
        unless dead $ do
          (_, que) <- getWorker gal
          atomically (writeTQueue que byt)

  let doKill :: IO ()
      doKill = do
        galas <- atomically $ do
          writeTVar vDead True
          readTVar vGala
        for_ galas (cancel . fst)

  pure (ResolvServ doSend doKill)
resolvServ
  :: HasLogFunc e
  => TVar (Maybe [Turf])
  -> (SockAddr -> ByteString -> IO ())
  -> (Text -> RIO e ())
  -> RIO e ResolvServ
resolvServ vTurfs send stderr = do
  vGala <- newTVarIO (mempty :: Map Galaxy (Async (), TQueue ByteString))
  vDead <- newTVarIO False
  envir <- ask

  let spawnWorker :: Galaxy -> IO (Async (), TQueue ByteString)
      spawnWorker gal = runRIO envir $ do
        que <- newTQueueIO
        las <- newTVarIO (Time.unixEpoch, Nothing)
        tid <- resolvWorker gal vTurfs las (readTQueue que) send stderr
        pure (tid, que)

  let getWorker :: Galaxy -> IO (Async (), TQueue ByteString)
      getWorker gal = do
        (fmap (lookup gal) $ atomically $ readTVar vGala) >>= \case
          Just (tid, que) -> do
            pure (tid, que)
          Nothing -> do
            (tid, que) <- spawnWorker gal
            atomically $ modifyTVar' vGala (M.insert gal (tid, que))
            pure (tid, que)

  let doSend :: Galaxy -> ByteString -> IO ()
      doSend gal byt = do
        dead <- atomically (readTVar vDead)
        unless dead $ do
          (_, que) <- getWorker gal
          atomically (writeTQueue que byt)

  let doKill :: IO ()
      doKill = do
        galas <- atomically $ do
          writeTVar vDead True
          readTVar vGala
        for_ galas (cancel . fst)

  pure (ResolvServ doSend doKill)
resolvServ vTurfs send stderr = do
  vGala <- newTVarIO (mempty :: Map Galaxy (Async (), TQueue ByteString))
  vDead <- newTVarIO False
  envir <- ask

  let spawnWorker :: Galaxy -> IO (Async (), TQueue ByteString)
      spawnWorker gal = runRIO envir $ do
        que <- newTQueueIO
        las <- newTVarIO (Time.unixEpoch, Nothing)
        tid <- resolvWorker gal vTurfs las (readTQueue que) send stderr
        pure (tid, que)

  let getWorker :: Galaxy -> IO (Async (), TQueue ByteString)
      getWorker gal = do
        (fmap (lookup gal) $ atomically $ readTVar vGala) >>= \case
          Just (tid, que) -> do
            pure (tid, que)
          Nothing -> do
            (tid, que) <- spawnWorker gal
            atomically $ modifyTVar' vGala (M.insert gal (tid, que))
            pure (tid, que)

  let doSend :: Galaxy -> ByteString -> IO ()
      doSend gal byt = do
        dead <- atomically (readTVar vDead)
        unless dead $ do
          (_, que) <- getWorker gal
          atomically (writeTQueue que byt)

  let doKill :: IO ()
      doKill = do
        galas <- atomically $ do
          writeTVar vDead True
          readTVar vGala
        for_ galas (cancel . fst)

  pure (ResolvServ doSend doKill)