External events from an action

Has anybody tried to generate an external event from an action? I’ve got a rather long process that I want to start in an action and then report when it’s complete letting the user continue on in the meantime. But it keeps blocking the code. If anyone had an example that did something like this that they could share I’d appreciate it.

Hi @Randywreed, is your action asynchronous? If it’s not, that is probably the reason why it is blocking, if it for example calls an HTTP request that takes a long time to complete.

You’ll want to define your action with

async def run(
    ...

and then instead of using a synchronous library like requests, use an asynchronous one like aiohttp. You can get started with the client example from their docs, but if you provide a code snippet of what you’re trying to achieve, that might help as well.

In the end (its been a long weekend of experimentation) the problem is that aiohttp requires a loop to work right which is problematic because rasa is already running a uvloop that doesn’t allow nesting. Otherwise it needs to do an await which blocks or create a task (fire and forget) which does the HTTP request in the background but generates an error because the result is not retrieved and screws up the next action so required a dummy action to clear the error. I’ll write a longer forum post for people trying to do this later, but essentially I resorted to using multiprocessing which did the request in the background, but didn’t generate an error. So using this works perfect in Rasa X local (though I can’t get it to work in rasa x using docker compose, if you had advice I’ve got another forum post https://forum.rasa.com/t/rasa-x-docker-compose-install-external-events-error/42113