0
$\begingroup$

I am trying to create a listener that sends a message through a Discord webhook to my Discord server. The issue that I am encountering at the moment is that I do not know how to create an asynchronous task in a synchronous callback (since according to the internet, an asynchronous callback does not exist).

task = self.event_loop.create_task(self._createLog(data)) stacks and is executed AFTER I initially terminate the Python program, and not while this callback is running. What do I do incorrectly here, and are there any other methods that are better practice to achieve this? Thanks in advance.

#!/usr/bin/env python3
import rospy
from std_msgs.msg import String
import asyncio
from discord_webhook import AsyncDiscordWebhook
from discord_webhook import DiscordEmbed


class listenerHandler:
    def _init_(self, discord_whurl: str, ros_node_name: str ,ros_topic: str):
        rospy.init_node(ros_node_name)

        self._last_post_unix = 0

        self._whurl = discord_whurl
        self._rt = ros_topic
        self._event_loop = asyncio.get_running_loop()
        print(self._event_loop)


    @property
    def webhook_url(self):
        return self._whurl
    
    @webhook_url.setter
    def webhook_url(self, url: str):
        self._whurl = url


    async def __sendLog(self, log: dict) -> None:
        print(log,' sending')
        self._embed = DiscordEmbed(title=log['title'], description=log['descripiton'], color="6dc5ff")

        self._webhook = AsyncDiscordWebhook(url=self._whurl)
        self._webhook.add_embed(self._embed)

        await self._webhook.execute()
        self._last_post_unix = rospy.get_time()

    async def __createLog(self, data) -> None:
        rospy.loginfo('creating log')
        log = {'title': self._rt, 'description': data.data}

        await self.__sendLog(log)


    def __callback(self, data):
        if rospy.get_time() - self._last_post_unix > 5:
            self._last_post_unix = rospy.get_time()
            print(rospy.get_time(), self._last_post_unix)
            rospy.loginfo('running loop')
            
            task = self.event_loop.create_task(self._createLog(data))

    def activate_listener(self):
        rospy.Subscriber(self._rt, String, self.__callback)

    async def async_spin(self):
        rospy.loginfo("beginning node spin")

        while not rospy.is_shutdown():
            pass


async def main():
    lh = listenerHandler(discord_whurl='https://discord.com/api/webhooks/1158359060140265503/deUeh_5dXFbmeoNeKwnRtWAMMnM7mI_4LtyXRtkpabYSq3oHGtzjY6rbJn9oT45QNXZV', ros_node_name='R_toDiscord_node' ,ros_topic='topic_1')
    lh.activate_listener()

    await lh.async_spin()

if _name_ == '_main_':
    asyncio.run(main())
```
$\endgroup$
2
  • 1
    $\begingroup$ Got it working by replacing task = self.event_loop.create_task(self._createLog(data)) with self._new_task = asyncio.run(self.__createLog(data)). I am not sure however, if this is good practice. $\endgroup$
    – Pogo
    Commented Oct 2, 2023 at 17:29
  • $\begingroup$ How much cpu does this node consume? If it's >= 100%, you're doing it wrong. To me, your async_spin() appears to just waste cpu cycles. $\endgroup$
    – Mike973
    Commented Oct 3, 2023 at 12:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.