I'm running an websocket application through Django Channels and with Python 3.12. I have a ping mechanism to check if my users are still connected to my application where at a fixed time interval the fronted sends a ping message to my server (let's say every 5 seconds) and when I receive that message I do the following:
I call await asyncio.sleep(time interval * 2) ;
Afterwards I check if the timestamp of the last message I received in this handler or in any other of the ones that is active is higher than time_interval * 1.5 and if it is I disconnect the user in order to free that connection resources since it isn't no longer active;
However we noticed that this sleep call we make every X seconds for each active connection that we have when a ping call is received may be causing some performance issues on the application as an all. We are assuming this because we noticed that every time we shut down this ping logic we need less resources (number of pods and CPU) to handle the median number of traffic we have then when we have this ping handler active. In other hand it seems that all the messages we serve through django channel also flow very much faster when this ping handler is disconnected.
My handler:
if action == "ping":
await self.ping_handler(message_info)
async def ping_handler(self, message_info):
await asyncio.sleep(PING_INTERVAL * 2)
if (
round_half_up(
(dt.datetime.now() - self.last_message).total_seconds(), decimals=0
)
>= PING_INTERVAL * 1.5
):
await self.close()
Besides this ping handler what my application does is receiving messages from clients, processes some of that messages data and then broadcast it to the appropriate channels like this:
async def action_dispatcher(self, action, message_info):
try:
if action == "post-message":
await self.handle_message(message_info)
elif action == "post-username":
await self.change_nickname()
elif action == "post-change-privacy":
await self.handle_change_privacy(message_info)
elif action == "get-bet-status":
await self.get_bet_status(message_info)
elif action == "ping":
self.last_message = dt.datetime.now()
await self.ping_handler(message_info)
async def handle_message(message_info):
# execute business logic before these steps
encoded_message = await super().encode_socket_message(
[
"message_type",
self.nickname,
"success",
]
)
await self.channel_layer.group_send(
self.username_group,
encoded_message,
)
Can someone help me understanding if my assumptions are right or wrong? I searched a lot around the internet and ChatGPT but I couldn't find a legitimate answer to my doubts that if we have 200 to 500 active connections in a channels application that every 5 seconds execute this ping logic that it could cause performance limitations.
The purpose of my application is to receive chat messages from clients, process their content and the broadcast it to the rest of the room through django channel layers.
I tried running my application with and without this ping handling logic and searched through foruns,stackoverflow questions and chat gpt to find aswers.