asyncio error on self.send()
I am...
- [X] Reporting a bug
I am running...
- Errbot version: 6.1.8
- OS version: Debian 11
- Python version: 3.9
- Using a virtual environment: yes
Issue description
I've got a very simple webhook plugin that should send a message to a room (XMPP backend) like this:
@webhook(raw=True)
def room(self, request):
data = request.get_json()
self.send(
self.build_identifier(data['room']), data['msg'],
)
Everytime the plugin would send a message, I run into an error with a missing async loop:
02:26:59 ERROR errbot.core_plugins Exception on /room [POST]
Traceback (most recent call last):
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/flask/app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/flask/app.py", line 1515, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/flask/app.py", line 1513, in full_dispatch_request
rv = self.dispatch_request()
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/flask/app.py", line 1499, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/flask/views.py", line 83, in view
return self.dispatch_request(*args, **kwargs)
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/errbot/core_plugins/wsview.py", line 77, in dispatch_request
response = self.func(request, **kwargs)
File "data/plugins/webhook/webhook.py", line 8, in room
self.build_identifier(data['room']), data['msg'],
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/errbot/botplugin.py", line 714, in build_identifier
return self._bot.build_identifier(txtrep)
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/errbot/backends/xmpp.py", line 604, in build_identifier
info = xep0030.get_info(jid=txtrep)
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/slixmpp/xmlstream/asyncio.py", line 15, in wrapper
result = func(*args, **kwargs)
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/slixmpp/plugins/xep_0030/disco.py", line 396, in get_info
return iq.send(timeout=kwargs.get('timeout', None),
File "/home/m00lean/.errbot-ve/lib/python3.9/site-packages/slixmpp/stanza/iq.py", line 188, in send
future = asyncio.Future()
File "/usr/lib/python3.9/asyncio/futures.py", line 79, in __init__
self._loop = events.get_event_loop()
File "/usr/lib/python3.9/asyncio/events.py", line 642, in get_event_loop
raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-17'.
Steps to reproduce
See above.
I have had this error before when using slixmpp, I think it's this issue.
A workaround for that issue is to add a piece of code to your plugin function, before it starts calling (xmpp) message functions:
import asyncio
try:
asyncio.get_event_loop()
except RuntimeError:
# slixmpp can not handle not having an event_loop
# see: https://lab.louiz.org/poezio/slixmpp/-/issues/3456
asyncio.set_event_loop(asyncio.new_event_loop())
However, after applying this fix, I get another error:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/usr/local/lib/python3.9/site-packages/flask/views.py", line 84, in view
return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/errbot/core_plugins/wsview.py", line 98, in dispatch_request
response = self.func(data, **kwargs)
File "/plugins/Notify/notify.py", line 15, in notify
self.build_identifier("REMOVED"),
File "/usr/local/lib/python3.9/site-packages/errbot/botplugin.py", line 716, in build_identifier
return self._bot.build_identifier(txtrep)
File "/usr/local/lib/python3.9/site-packages/errbot/backends/xmpp.py", line 615, in build_identifier
disco_info = info["disco_info"]
TypeError: '_asyncio.Future' object is not subscriptable
Maybe errbot has not adapted to recent changes in the slixmpp interface, in particular its asyncio nature? Just guessing here.
Errbot is not setup to use asyncio. It's all threaded.
Errbot is not setup to use asyncio. It's all threaded.
Right. However slixmpp does use asyncio, and apparently we can't completely avoid using it -- at least the documented way to send a message to a specific recipient -- hich is also the way to send a message at all from a webhook IIUC -- fails to work with the xmpp backend because of this.
I'll try to encapsulate the asyncio functions where errbot calls them, but my first attempt at that failed: the process calling the webhook hangs because it never receives a response from errbot. I hope to debug that further later when I have time again to work on this.