тип expression
Хотя непонятно, зачем парсить строку с прокси, если ее можно целиком вставить и бас сам все сделает. Только тип прокси указать нужный. А если пркоси идет с протоколом (типа socks5://proxy:port:login:pass), то можно тип ставить auto
Асинхронная функция запускается из основного потока. Сам скрипт многопоточный, и в каждом потоке БАСа запускается асинхронная функция как-то так:
Main:
-- действия 1
-- async function
-- действия 2.
В режиме запуска выполняются все действия потока, но поток ждет, пока асинхронная функция не завершит работу и не запускает новый поток. Как сделать так, чтобы асинхронная функция запускалась как демон, не приводя к ожиданию ее завершения потоком, из которого она была запущена?
Вот настройки:

Можно запускать ее в onApplicationStart, но это не очень подходит.
Вы пытаетесь сделать многопоток в многопотоке ... Упростить никак ?
Задачу опишите и может подскажут ...
В скрипте нужно отменять активации номеров. Если отменить номер незадолго после взятия, то сервис СМС вернет ошибку. Поэтому я сделал функцию, которая в течение 2 минут пробует отменить номер, и вызываю ее как асинхронную функцию. Чтобы отмена номера выполнялась как фоновая задача, и основные потоки ее не ждали.
Ожидаемое поведение: поток баса вызывает функцию отмены номера и, не дожидаясь результата асинхронной функции, запускает следующее выполнение.
Как работает по факту: поток вызывает функцию асинхронно, не дожидаясь ее завершения, выполняет действия до конца. Но не запускает следующее выполнение, а ждет пока асинхронная функция завершится.
Как можно сделать:
Вызывать асинхронную функцию из onApplicationStart, брать таски на отмену из какой-нибудь очереди, вроде базы данных или глобальной переменной. Но тогда будет ряд проблем:
В общем, значительно проще запускать фоновую задачу из обычного потока, и передавать ей что нужно. Но очень странно, что поток ждет асинхронную функцию.
P.S. Написал тестовый шаблон, но он работает нормально, магия какая-то.
test_async_function.xml
Так не ждите выполнения асинхронной - там по сути просто гет запрос ... даже если в цикле ... По идеи вообще один ...
@thepappo said in Нормальное завершение потока, из которого запускается асинхронная функция:
В скрипте нужно отменять активации номеров. Если отменить номер незадолго после взятия, то сервис СМС вернет ошибку.
Я написал отдельный скрипт, который по API получает номера, которые вот-вот истекут и отменяет их. Скрипт запускается в цикле каждую минуту.
Например, номер дается на 20 минут, поток в скрипте у меня не может взять номер на это время, а может, к примеру на 5 минут максимум, значит я могу смело отменять все номера, которые были взяты более 15 минут назад.
5 минут взяты для примера. Я знаю, что я беру номер из сервиса, что-то там делаю, жду смс-ку и все это занимает у меня максимум эти самые 5 минут.
Сам скрипт ни о каких потоках, скриптах и так далее понятия не имеет и работает автономно.
import logging
import os
import datetime
import time
from dotenv import load_dotenv
from smsactivate.api import SMSActivateAPI
# Configure logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("[sms_activate]")
# Load environment variables from .env file
ABS_PATH = os.path.dirname(os.path.abspath(__file__))
load_dotenv()
def main(api_key: str, threshold_seconds: int = 15 * 60):
"""
Main function to check and process active activations.
Args:
api_key (str): API key for SMSActivate service.
threshold_seconds (int): Threshold in seconds to consider activation time.
Returns:
None
"""
sa = SMSActivateAPI(api_key)
sa.debug_mode = True
# Get active activations
activations = sa.getActiveActivations()
if activations.get("error") == 'NO_ACTIVATIONS':
logger.info("No pending activations found.")
return False
# Check if activations retrieval was successful
if activations.get("status") != 'success':
raise Exception("Activation status is not success")
# Loop through active activations
for one in activations["activeActivations"]:
if one["smsCode"]:
# Skip if activation is already used
continue
# Parse activation time
activation_time_str = one["activationTime"]
activation_time = datetime.datetime.strptime(activation_time_str, '%Y-%m-%d %H:%M:%S')
current_time = datetime.datetime.now()
# Calculate time difference in seconds
time_difference = current_time - activation_time
seconds_difference = time_difference.total_seconds()
# Log the time difference
logger.info("Seconds difference from activation time to now: %s" % seconds_difference)
# Check if activation time exceeds threshold
if seconds_difference > threshold_seconds:
logger.info("Activation time exceeds threshold for: %s" % one)
# Mark activation as used
sa.setStatus(id=one["activationId"], status=8)
if __name__ == '__main__':
# Get SMS Activate API key from environment variables
sms_activate_api_key = os.getenv("SMS_ACTIVATE_API_KEY")
if not sms_activate_api_key:
raise Exception('SMS_ACTIVATE_API_KEY environment variable not set')
sms_activate_api_key = sms_activate_api_key.strip()
time_to_sleep = 60
while True:
try:
main(api_key=sms_activate_api_key)
except Exception as e:
# Log any exceptions
logger.error(e)
# Wait for 60 seconds before checking again
logger.info(f"Sleeping for {time_to_sleep} seconds")
time.sleep(time_to_sleep)
@thepappo понял, во все просто оказывается ... Сергедрын взял и все по полочкам разложил ... Я правда его задачи до конца не понял, по какой причине поток не может взять больше чем на пять, и почему если он не дождался не может отбить что не судьба, но главное все по уму, по науке ....
@Nicolas said in Нормальное завершение потока, из которого запускается асинхронная функция:
Так не ждите выполнения асинхронной
В том и прикол, что я не жду. В предыдущем посте шаблон выложил тестовый, он нормально работает. А рабочий - нет ). Очевидно, что-то накосячил я сам.
@thepappo said in Нормальное завершение потока, из которого запускается асинхронная функция:
@sergerdn так а при чем тут питон?
Можно реализовать эту логику на каком угодно языке.
И получить тоже самое, один автономный скрипт отмены и куча скриптов на BAS, что берут номера из смс-сервиса и не имеют никакой логики отмены их. Я пишу всякие утилиты на python, ты можешь писать на чем угодно.
@thepappo said in Нормальное завершение потока, из которого запускается асинхронная функция:
@Nicolas said in Нормальное завершение потока, из которого запускается асинхронная функция:
Так не ждите выполнения асинхронной
В том и прикол, что я не жду. В предыдущем посте шаблон выложил тестовый, он нормально работает. А рабочий - нет ). Очевидно, что-то накосячил я сам.
в ошибку и на фейл внутри асинхронной ...
@sergerdn said in Нормальное завершение потока, из которого запускается асинхронная функция:
один автономный скрипт отмены и куча скриптов на BAS
Я понимаю, что можно. Я выше и про запуск демона из onApplicationStart писал. И я сам пишу на питоне ). Но в данном случае надо было именно из потока запускать таску.