Skip to content Skip to sidebar Skip to footer

Discord.gateway Warning "Shard ID None Heartbeat Blocked For More Than 10 Seconds." While Using Pandas

So I've made a discord bot using discord.py in python and have been running it for some time. However, recently the bot has randomly started to die. So I added the logging library

Solution 1:

The warning essentially means that your code is blocking for more than x seconds, it blocks the heartbeat and triggers that warning (you can reproduce this with time.sleep(x)). To fix it, you have to run the blocking functions (the panda ones) in a non-blocking way:

import time # To reproduce the error
import typing # For typehinting 
import functools

def blocking_func(a, b, c=1):
    """A very blocking function"""
    time.sleep(a + b + c)
    return "some stuff"


async def run_blocking(blocking_func: typing.Callable, *args, **kwargs) -> typing.Any:
    """Runs a blocking function in a non-blocking way"""
    func = functools.partial(blocking_func, *args, **kwargs) # `run_in_executor` doesn't support kwargs, `functools.partial` does
    return await client.loop.run_in_executor(None, func)


@client.command()
async def test(ctx):
    r = await run_blocking(blocking_func, 1, 2, c=3) # Pass the args and kwargs here
    print(r) # -> "some stuff"
    await ctx.send(r) 

You should run all the blocking functions this way

Another (easier) way would be to simply create a decorator

import functools
import typing
import asyncio


def to_thread(func: typing.Callable) -> typing.Coroutine:
    @functools.wraps(func)
    async def wrapper(*args, **kwargs):
        return await asyncio.to_thread(func, *args, **kwargs)
    return wrapper


@to_thread
def blocking_func(a, b, c=1):
    time.sleep(a + b + c)
    return "some stuff"


await blocking_func(1, 2, 3)

If you're using python <3.9 you should use loop.run_in_executor instead of asyncio.to_thread

def to_thread(func: typing.Callable) -> typing.Coroutine:
    @functools.wraps(func)
    async def wrapper(*args, **kwargs):
        loop = asyncio.get_event_loop()
        wrapped = functools.partial(func, *args, **kwargs)
        return await loop.run_in_executor(None, func)
    return wrapper


@to_thread
def blocking_func(a, b, c=1):
    time.sleep(a + b + c)
    return "some stuff"


await blocking_func(1, 2, 3)

Post a Comment for "Discord.gateway Warning "Shard ID None Heartbeat Blocked For More Than 10 Seconds." While Using Pandas"