Sunday, 19 June 2022

discord.py invites - approximate_presence_count API gradually becomes slower

TL/DR: I'm querying an invite link's approximate_presence_count every 10 seconds, and it gradually stops detecting presence changes over a very long period. How can I fix this?

Goal

I'm writing a discord bot which monitors the number of online (and other statuses) members in several large (>100 members) servers I'm a member of. The bot is not a member of any of the relevant servers, and should log the number of members every 10 seconds or so.

This is not an XY problem, I do not want the bot to be a member of the servers, and simply just want it to use approximate_presence_count from invite links.

Method

To do this, I've made permanent invite links to each of the servers, and I query their approximate_presence_count at 10-second intervals via a tasks.loop, logging those values to a text file.

Additionally, I have a small testing server in which I have several friends who log on and off, to test whether the member count is working.

All intents are enabled in the developer portal. This is not an intents-related issue.

Problem

During testing on my small testing server, whilst running the bot over approximately a 24-hour period, I noticed that it becomes slower and slower to detect changes in approximate_presence_count after one of my friends logs on or off discord. I've reproduced this on several different days. While there is some minor variation in the time for approximate_presence_count to update at any given time, presumably due to the discord backend having variable amounts of load, this trend is constant.

After about 20-24 hours, the approximate_presence_count becomes almost useless, rarely detecting any changes.

Expected result: Delay between logon/logoff and change in approximate_presence_count remains constant

Actual result: Delay between logon/logoff and change in approximate_presence_count gradually increases

What I've tried

In addition to the code below, I also tried not fetching the invites every single time logger loops, but this also did not work.

I can reproduce the info on more than one network, and on more than one machine.

Minimal reproducible example

The code below is extracted from the bot and should be only the relevant components. There may be mistakes in the extraction process, but the gist remains the same.

import discord
from discord.ext import tasks

TOKEN='removed'
INTENTS=discord.Intents.all()
links=['discord.gg/foobarbaz','discord.gg/fillertext']#real invites removed

client = discord.Client(intents=INTENTS)

@tasks.loop(seconds=10)
async def logger():
  invites=[await client.fetch_invite(i,with_counts=True)for i in links]#invite objects
  counts=[getattr(i,'approximate_presence_count')for i in invites]#presence counts
  
  with open('logs.txt','a') as file:
    file.write(datetime.datetime.today().strftime("%d/%m/%Y, %H:%M:%S ")+','.join(map(str,counts))+'\n')

@client.event
async def on_ready():
  logger.start()

client.run(TOKEN)

Final notes

The expected delay in approximate_presence_count

In my testing when this issue does not occur, the delay between logon/logoff and the change in approximate_presence_count is between 5 and 40 seconds, with perhaps 1 in 100 being up to 60 seconds.

Number of invites tracked

The bot is tracking 6 invite links currently, so the frequency of requests to Discord is 0.6/second on average. Is this enough to cause a ratelimit, perhaps? As EricJin mentioned in the comments, this is unlikely.



from discord.py invites - approximate_presence_count API gradually becomes slower

No comments:

Post a Comment