I have a script that is constantly running forever (it checks changes in files). I need to send Discord messages whenever a weird file is made.
- Problem is, the event watching function (
def run(self):below) is from a subclass, so I can't change it toasync def run(self):. Therefore I can't useawait channel.send() - My solution to this was to use
run_coroutine_threadsafelike explained here: https://stackoverflow.com/a/53726266/9283107. That works good! But the problem is, the messages get put into a queue and they never get sent until this script finishes (which in my case would be: never). I assume the send message functions get put into the thread that this script is on, therefore the thread never gets to them?
Maybe we can throw the run_coroutine_threadsafe into a separate thread or something? This is the most minimal example I can make that still shows my subclass problem.
import discord
import os
import asyncio
import time
# CHANNEL_ID = 7659170174????????
client = discord.Client()
channel = None
class Example():
# Imagine this run comes from a subclass, so you can't add sync to it!
def run(self):
# await channel.send('Test') # We can't do this because of the above comment
asyncio.run_coroutine_threadsafe(channel.send('Test'), _loop)
print('Message sent')
@client.event
async def on_ready():
print('Discord ready')
global channel
channel = client.get_channel(CHANNEL_ID)
for i in range(2):
Example().run()
time.sleep(3)
print('Discord messages should appear by now. Sleeping for 20s to give it time (technically this would be infinite)')
time.sleep(20)
print('Script done. Now they only get sent for some reason')
_loop = asyncio.get_event_loop()
client.run('Your secret token')
time.sleep()from anasync def. What you should do is spawn a background thread (using something likethreading.Thread(target=checker_function, args=(asyncio.get_event_loop(),)).start()) fromon_readyor even from top-level code, wherechecker_functionwill executeExample().run(). Your main thread will run the asyncio event loop and your background thread will check the files, usingasyncio.run_coroutine_threadsafe()to communicate with asyncio/discord.asyncio.run_coroutine_threadsafe()assumes that you have multiple threads running (hence "thread-safe"), and here you obviously have only one. Until you change that, any attempt to useasyncio.run_coroutine_threadsafe()will fail.asyncio.run_coroutine_threadsafeis just a convenience function that can be called from another thread to "wake up" the event loop and tell it to do something.