summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrebecca <ubq323@ubq323.website>2026-09-13 18:22:30 +0100
committerrebecca <ubq323@ubq323.website>2026-09-13 18:22:50 +0100
commit86ff06f140d6122dc38d9fad2b29ca7eccc82171 (patch)
treeeb4aec73d069da7dd447426facc84147b99b4661
parente866f674651d590706b586a346957576c2b7d55c (diff)
discord: implement ratelimiting
-rw-r--r--discord/pylon.lua26
1 files changed, 21 insertions, 5 deletions
diff --git a/discord/pylon.lua b/discord/pylon.lua
index 3281c53..358fd8f 100644
--- a/discord/pylon.lua
+++ b/discord/pylon.lua
@@ -25,6 +25,7 @@ local function identify_payload(token)
token = token } } end
function Discord._req(self, url, payload)
+ ::again::
local req = request.new_from_uri(API_BASE..url)
req.headers:upsert(':method',payload and 'POST' or 'GET')
req.headers:upsert('authorization','Bot '..self.token)
@@ -32,10 +33,27 @@ function Discord._req(self, url, payload)
if payload then
req.headers:upsert('content-type','application/json')
req:set_body(assert(json.encode(payload))) end
+
local head,body = assert(req:go())
local status = head:get':status'
local bod = body:get_body_as_string()
- assert(status:match"^2", 'status was '..status..' body '..bod)
+
+ assert(status:match"^2" or status=="429", 'status was '..status..' body '..bod)
+
+ local rl_rem = tonumber(head:get'x-ratelimit-remaining')
+ local rl_wait = tonumber(head:get'x-ratelimit-reset-after')
+ self.log:debug('ratelimit',rl_rem,rl_wait)
+ if status == "429" then
+ self.log:warn("getting 429'd, waiting",rl_wait)
+ cqueues.sleep(rl_wait)
+ goto again
+ elseif rl_rem < 5 then
+ local wait = rl_wait -- or rl_wait/(rl_rem+1)? their algorithm is mysterious
+ self.log:info("ratelimit limit getting low ",rl_rem,", waiting",wait)
+ if wait>5 then self.log:warn("isn't",wait,"a little long to be waiting?") end
+ cqueues.sleep(wait)
+ end
+
if #bod == 0 then return nil end
local val, _, err = json.decode(bod)
if err then error(err) else return val end
@@ -90,8 +108,8 @@ end
function Discord.recving(self)
for packet in self.ws:each() do
local event = json.decode(packet)
- self.log:debug(event.s, event.op, event.t)
- if event.op ~= opcodes.dispatch then
+ self.log:debug('event',event.s, event.op, event.t)
+ if false and event.op ~= opcodes.dispatch then
self.log:debug(event.d)
end
@@ -119,8 +137,6 @@ function Discord.handle_dispatch(self, event)
sender = '[d]' .. d.author.username,
})
end
- elseif event.t == 'READY' then
- self.log:debug(event.d)
end
end