How to handle concurrent long tasks in the action server

Hi, i’m calling an API from my action server which takes about 20 seconds or more to get the job completed. So that, the action server can’t handle more requests while it’s busy waiting for another response. I heard that one option was to implement the function asynchronously, however i have been studying how to do it but still don’t know to implement it in rasa. Please your kind help with this, thanks.

class GenerarLink(Action):

def name(self) -> Text:
    return "generarLinkRPA"

def run(self, dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
    empresa=tracker.get_slot('empresa')
    banco=tracker.get_slot('banco')
    print('el banco es :'+str(banco))
    correoPSE=tracker.get_slot('correoPSE')
    numeroFactura=tracker.get_slot('numeroFactura')
    response = requests.get(
        'http://localhost:5000/',
        params={'numeroFactura': numeroFactura, 'empresa':empresa,'banco':banco,'correoPSE':correoPSE},
        )
    link=response.text
    print(link)
    if len(link)>2 and response.status_code==200:
        error=False
    else: error =True    
    if error==False:
        #tracker.slots['errorRPA']='no'
        print('no hay error')
        dispatcher.utter_message(text='Puedes pagar tu factura en este link de '+tracker.get_slot('banco')+': '+link)
        return[SlotSet('errorRPA', 'no')]
    else:
        #tracker.slots['errorRPA']='si'
        print('hubo un error')
        dispatcher.utter_message(text='Parece ser que hubo un error')
        return[SlotSet('errorRPA', 'si')]

There’s a lovely tutorial on asyncio here in case you’re interested.

Out of curiosity. Did you benchmark how long it takes to get a response from http://localhost:5000?

I’ve never written custom actions asynchronously so I’m not 100% sure if they’re supported. I’ll try to ping a colleague.

Hi @franciscoreales1,

you can also use async custom action :+1: See our new docs on it here

Thanks @Tobias_Wochinger!

He just forwarded me this docs page it seems that async is the default. What you might need to look at though is using a tool like httpx instead of requests. If I recall correctly the requests library is not async and therefore might be blocking.

@Tobias_Wochinger and @koaning, I ended up implementing the request using aiohttp and worked just fine! Thank you very much for your help.

1 Like