discord-haskell 1.1.2 → 1.1.3
raw patch · 4 files changed
+21/−20 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- changelog.md +4/−0
- discord-haskell.cabal +1/−1
- src/Discord/Internal/Rest/HTTP.hs +15/−18
- src/Discord/Internal/Rest/Prelude.hs +1/−1
changelog.md view
@@ -4,6 +4,10 @@ ## master +## 1.1.3++Minor improvements to rate-limiting like using newer `X-RateLimit-Reset-After` header+ ## 1.1.2 [michalrus](https://github.com/aquarial/discord-haskell/issues/25) Fix `DeleteGuildRole` parse exception
discord-haskell.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.0 name: discord-haskell -- library version is also noted at src/Discord/Rest/Prelude.hs-version: 1.1.2+version: 1.1.3 description: Functions and data types to write discord bots. Official discord docs <https://discordapp.com/developers/docs/reference>. .
src/Discord/Internal/Rest/HTTP.hs view
@@ -19,14 +19,13 @@ import Control.Concurrent.MVar import Control.Concurrent.Chan import Data.Ix (inRange)-import Data.List (isPrefixOf) import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime) import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL import qualified Data.Text as T import qualified Data.Text.Encoding as TE-import Data.Maybe (fromMaybe) import Text.Read (readMaybe)+import Data.Maybe (fromMaybe) import qualified Network.HTTP.Req as R import qualified Data.Map.Strict as M @@ -50,7 +49,7 @@ Locked -> do writeChan urls (route, request, thread) loop ratelocker Available -> do let action = compileRequest auth request- reqIO <- try $ restIOtoIO (tryRequest action)+ reqIO <- try $ restIOtoIO (tryRequest log action) case reqIO :: Either R.HttpException (RequestResponse, Timeout) of Left e -> do writeChan log ("rest - http exception " <> T.pack (show e))@@ -70,15 +69,9 @@ <> T.pack (show ((i - curtime) * 1000))) threadDelay $ round ((i - curtime + 0.1) * 1000) loop ratelocker- PathWait i -> loop $ M.insert route (if isPrefixOf "add_react " route- then curtime + 0.25 else i)- (removeAllExpire ratelocker curtime)+ PathWait i -> loop $ M.insert route i (removeAllExpire ratelocker curtime) NoLimit -> loop ratelocker --- Note: we hardcode delay for CreateReaction ("add_react")--- why the headers are wrong: https://github.com/discordapp/discord-api-docs/issues/182--- why I chose to hardcode it: https://github.com/aquarial/discord-haskell/issues/16- data RateLimited = Available | Locked compareRate :: M.Map String POSIXTime -> String -> POSIXTime -> RateLimited@@ -101,17 +94,20 @@ | PathWait POSIXTime | NoLimit -tryRequest :: RestIO R.LbsResponse -> RestIO (RequestResponse, Timeout)-tryRequest action = do+tryRequest :: Chan T.Text -> RestIO R.LbsResponse -> RestIO (RequestResponse, Timeout)+tryRequest _log action = do resp <- action- next10 <- liftIO (round . (+10) <$> getPOSIXTime)+ now <- liftIO getPOSIXTime let body = R.responseBody resp code = R.responseStatusCode resp status = R.responseStatusMessage resp- remain = fromMaybe 1 $ readMaybeBS =<< R.responseHeader resp "X-Ratelimit-Remaining"- global = fromMaybe False $ readMaybeBS =<< R.responseHeader resp "X-RateLimit-Global"- resetInt = fromMaybe next10 $ readMaybeBS =<< R.responseHeader resp "X-RateLimit-Reset"- reset = fromIntegral resetInt+ global = (Just "true" ==) $ readMaybeBS =<< R.responseHeader resp "X-RateLimit-Global"+ remain = fromMaybe 1 $ readMaybeBS =<< R.responseHeader resp "X-RateLimit-Remaining"+ reset = withDelta . fromMaybe 10 $ readMaybeBS =<< R.responseHeader resp "X-RateLimit-Reset-After"++ withDelta :: Double -> POSIXTime+ withDelta dt = now + fromRational (toRational dt)+ if | code == 429 -> pure (ResponseTryAgain, if global then GlobalWait reset else PathWait reset) | code `elem` [500,502] -> pure (ResponseTryAgain, NoLimit)@@ -127,7 +123,8 @@ compileRequest :: Auth -> JsonRequest -> RestIO R.LbsResponse compileRequest auth request = action where- authopt = authHeader auth+ authopt = authHeader auth <> R.header "X-RateLimit-Precision" "millisecond"+ action = case request of (Delete url opts) -> R.req R.DELETE url R.NoReqBody R.lbsResponse (authopt <> opts) (Get url opts) -> R.req R.GET url R.NoReqBody R.lbsResponse (authopt <> opts)
src/Discord/Internal/Rest/Prelude.hs view
@@ -25,7 +25,7 @@ where -- | https://discordapp.com/developers/docs/reference#user-agent -- Second place where the library version is noted- agent = "DiscordBot (https://github.com/aquarial/discord-haskell, 1.1.2)"+ agent = "DiscordBot (https://github.com/aquarial/discord-haskell, 1.1.3)" -- Append to an URL infixl 5 //