module Calamity.Client.ShardManager
( shardBot ) where
import Calamity.Client.Types
import Calamity.Gateway
import Calamity.HTTP
import Calamity.Internal.Utils
import Control.Concurrent.MVar
import Control.Concurrent.STM
import Control.Lens
import Control.Monad
import Data.Traversable
import Fmt
import Polysemy ( Sem )
import qualified Polysemy as P
import qualified Polysemy.Reader as P
aa :: (Show a, Monad m) => Either a b -> m b
aa (Right x) = pure x
aa (Left x) = fail $ show x
shardBot :: BotC r => Sem r ()
shardBot = do
numShardsVar <- P.asks numShards
shardsVar <- P.asks shards
hasShards <- P.embed $ not . null <$> readTVarIO shardsVar
when hasShards $ fail "don't use shardBot on an already running bot."
token <- P.asks Calamity.Client.Types.token
eventQueue <- P.asks eventQueue
gateway <- aa =<< invokeRequest GetGatewayBot
let numShards' = gateway ^. #shards
let host = gateway ^. #url
P.embed $ putMVar numShardsVar numShards'
info $ "Number of shards: " +| numShards' |+ ""
shards <- for [0 .. numShards' - 1] $ \id ->
newShard host id numShards' token eventQueue
P.embed . atomically $ writeTVar shardsVar shards