Какие существуют способы организации фоновых задач в Python без использования Celery

Ответ

Для выполнения фоновых задач в Python без Celery можно использовать как встроенные модули, так и легковесные библиотеки. Выбор зависит от типа задачи и сложности инфраструктуры.

1. Встроенные модули

  • threading: Идеально для I/O-bound задач (например, сетевые запросы, работа с файлами), где основной процесс ожидает завершения внешних операций. Не подходит для CPU-bound задач из-за Global Interpreter Lock (GIL).

    from threading import Thread
    import time
    
    def slow_network_request(data):
        print(f"Starting request with {data}...")
        time.sleep(5)
        print("Request finished.")
    
    # Задача выполняется в фоновом потоке, не блокируя основной
    thread = Thread(target=slow_network_request, args=("some_data",))
    thread.start()
    print("Основной поток продолжает работу.")
  • multiprocessing: Подходит для CPU-bound задач (сложные вычисления, обработка данных), так как позволяет обойти ограничения GIL, запуская задачи в отдельных процессах. Более ресурсоемкий, чем threading.

    from multiprocessing import Process
    
    def cpu_intensive_task():
        # Имитация тяжелых вычислений
        sum(i * i for i in range(10**7))
        print("CPU-bound task finished.")
    
    process = Process(target=cpu_intensive_task)
    process.start()
    print("Основной процесс не ждет завершения вычислений.")

2. Легковесные библиотеки-очереди

Если требуется персистентность, очереди задач и повторные попытки, но Celery кажется избыточным, стоит рассмотреть:

  • RQ (Redis Queue): Простая в настройке библиотека, использующая Redis в качестве брокера сообщений. Отлично подходит для большинства веб-приложений.

    # app.py
    from redis import Redis
    from rq import Queue
    from tasks import count_words
    
    q = Queue(connection=Redis())
    # Асинхронный вызов задачи
    job = q.enqueue(count_words, 'http://example.com')
  • Huey: Легковесная альтернатива с поддержкой периодических задач, отложенного выполнения и хранения результатов. Может использовать Redis, SQLite или работать в памяти.

Ответ 18+ 🔞

Ну ты смотри, какие у нас тут варианты для фоновых дел в Python, если Celery — это как привезти КамАЗ, чтобы хлеб из магазина привезти. Перебор, блядь.

1. То, что в коробке уже лежит

  • threading: Это когда тебе надо, чтобы пока комп тупит, ждёт ответа от сервера или файл читает, основная программа не вставала столбом. Для CPU-задач — нихуя не годится, там GIL, эта сука, всё в один поток зажимает.

    from threading import Thread
    import time
    
    def slow_network_request(data):
        print(f"Starting request with {data}...")
        time.sleep(5)
        print("Request finished.")
    
    # Запускаем в фоне, и пошли дальше, не ждём
    thread = Thread(target=slow_network_request, args=("some_data",))
    thread.start()
    print("Основной поток продолжает работу.")
  • multiprocessing: А вот это уже для серьёзных вычислений, где мозги нужны. Запускает отдельный процесс, и GIL ему похуй. Жрёт, конечно, ресурсов побольше, но зато работает.

    from multiprocessing import Process
    
    def cpu_intensive_task():
        # Допустим, тут какая-то ебейшая математика
        sum(i * i for i in range(10**7))
        print("CPU-bound task finished.")
    
    process = Process(target=cpu_intensive_task)
    process.start()
    print("Основной процесс не ждет завершения вычислений.")

2. Библиотечки полегче, но с мозгом

Если тебе надо, чтобы задачи в очередь встали, на случай если всё ебнется, и чтобы их можно было перезапустить — но поднимать целый Celery, это как из пушки по воробьям, ёпта.

  • RQ (Redis Queue): Проще пареной репы. Кинул задачу в Redis — и забыл. Идеально для веба.

    # app.py
    from redis import Redis
    from rq import Queue
    from tasks import count_words
    
    q = Queue(connection=Redis())
    # Отправил и пошёл пить чай, пока оно само делается
    job = q.enqueue(count_words, 'http://example.com')
  • Huey: Вообще хитрая жопа. Может и по расписанию работать, и результаты хранить, и в Redis, и в SQLite, и просто в памяти. Универсальный солдатик, блядь.

Короче, смотри по задаче. Не надо тут ебаться с Celery, если можно проще. Всё гениальное — просто, а сложное — обычно нахуй не нужно.