Как реализовать многопоточность в телеграм боте?

Я испрлЬзую aiogram для работы с телегой и мне нужно реализовать многопотчность одной функции:

def check_cred(LastName:str,FirstName:str,MidName:str,number:int):
    browser = webdriver.PhantomJS(executable_path='/home/minicx/Документы/rcoi/phantomjs')
    wait=WebDriverWait(browser,500)
    browser.get('xxxxx')
    wait.until(EC.element_to_be_clickable((By.XPATH,'//*[@id="ctl00_LastName"]')))
    browser.find_element_by_xpath('//*[@id="ctl00_LastName"]').send_keys(LastName)
    browser.find_element_by_xpath('//*[@id="ctl00_FirstName"]').send_keys(FirstName)
    browser.find_element_by_xpath('//*[@id="ctl00_MidName"]').send_keys(MidName)
    browser.find_element_by_xpath('//*[@id="ctl00_Number"]').send_keys(number)
    browser.find_element_by_xpath('//*[@id="ctl00_AcceptDataProcessing"]').click()
    wait.until(EC.element_to_be_clickable((By.XPATH,'//*[@id="ctl00_LoginButton"]')))
    browser.find_element_by_xpath('//*[@id="ctl00_LoginButton"]').click()
    try:
        if (browser.find_element_by_xpath('/html/body/form/table/tbody/tr[1]/td[2]/div/table/tbody/tr/td/table/tbody/tr[6]/td').text.find("Неудачно")!=-1):
            return False
    except:
        return True

А вот кусочек из телеграмма:

   with concurrent.futures.ThreadPoolExecutor() as executor:
        try:
            succesfull=executor.submit(lambda : scraper.check_cred(info[0],info[1],info[2],int(info[3]))).result()
        except Exception: succesfull=False; await bot.send_message(message.chat.id,"Неверные данные!")

Ответы (1 шт):

Автор решения: Roman Konoval

Проблема в том, что в обработчике вызывается result(). Эта функция останавливает текущий поток, пока не будет готов результат (т.е. не закончит свое выполнение и не выполнит return) функции, которую передали в submit.

Правильно решение, это закончить обработчик стразу же, но после окончания работы функции из другого потока, продолжить выполнение:

Если было:

with concurrent.futures.ThreadPoolExecutor() as executor:
  try:
     succesfull=executor.submit(lambda : scraper.check_cred(info[0],info[1],info[2],int(info[3]))).result()
  except Exception:
     succesfull=False
     await bot.send_message(message.chat.id,"Неверные данные!")
if successful:
     await bot.send_message(message.chat.id, "Успех!")

Нужно сделать так:

async def continue_after_check(successful, chat_id):
  if successful:
     await bot.send_message(chat_id, "Успех!")
  else:
     await bot.send_message(chat_id, "Неверные данные!")
 
def check_cred(loop, scraper, info, chat_id):
  try:
    successful = scraper.check_cred(info[0],info[1],info[2],int(info[3])))
  except:
    successful = false
  asyncio.run_coroutine_threadsafe(
        continue_after_check(successful, chat_id), loop)


# код в обработчике сообщения
asyncio.to_thread(
   check_cred, asyncio.get_event_loop(), scraper, info, message.chat.id
)

# можно и через ThreadPoolExecutor
with concurrent.futures.ThreadPoolExecutor() as executor:
  executor.submit(check_cred, asyncio.get_event_loop(), scraper, info, message.chat.id)
→ Ссылка