Обновление модели БД в apply_async не выполняется

#python #flask

#питон #фляжка #python #flask

Вопрос:

Я пытаюсь сделать неблокирующий http-запрос с помощью pool.apply_async и после получения ответа обновите существующий db raw новым значением. Все идет нормально, пока я не пытаюсь обновить значение, я получаю сообщение об ошибке «Приложение не найдено. Либо работайте внутри функции просмотра, либо нажимайте контекст приложения». Можете ли вы помочь мне понять, почему?

models.py

 class Proxy(db.Model):
    __tablename__ = 'Proxy'
    __table_args__ = {'extend_existing': True}

    id = Column(Integer, primary_key=True, autoincrement=True)
    ip_address = Column(db.String(20))
    port_number = Column(db.String(7))
    proxy_type = Column(db.String(7))
    username = Column(String(100))
    password = Column(String(100))
    status = Column(Integer, default=0)
    user_id = Column(Integer, ForeignKey('User.id'))
    proxies = relationship("User", backref=backref("Proxies", cascade="all,delete"))

    def __init__(self, **kwargs):
        db.Model.__init__(self, **kwargs)

    def __repr__(self):
        return '{}:{}@{}:{}'.format(self.username, self.password, self.ip_address, self.port_number)

    def __getitem__(self, key):
        return getattr(self, key)

    def __setitem__(self, key, value):
        if key in self:
            setattr(self, key, value)
  

routers.py

 from app.base.models import Proxy 
pool = Pool(10)
proxy = ProxyModel.query.join(UserModel).filter(UserModel.id == current_user.id).filter(ProxyModel.id == proxy_id).first()

pool.apply_async(long_running_job, args=[proxy])

def long_running_job(proxy):
    proxies = {
        "http": "socks5h://"   str(proxy) if proxy.proxy_type == 'socks5' else "http://"   str(proxy),
        "https": "socks5h://"   str(proxy) if proxy.proxy_type == 'socks5' else "https://"   str(proxy),
    }
    with suppress(Exception):
        response = requests.get('https://graph.facebook.com/', proxies=proxies, timeout=5)

        if response and 'Unsupported get request' in response.text:
            print('Valid')
            proxy.status = 1
            db.session.commit()
        else:
            print('INValid')
            proxy.status = -1
            db.session.commit()
  

Ответ №1:

Возможные причины сбоя:

  1. apply_async ожидается, что аргументы будут кортежем. Используйте pool.apply_async(long_running_job, args=(proxy,)) вместо
  2. Как говорится в методе, операция является асинхронной, поэтому ее можно завершить в любое время. Вы можете использовать callback параметр, чтобы увидеть, когда он завершится, поместив, например: callback=lambda x: print("Finished task")
  3. Произошла любая другая ошибка. Для отслеживания этих ошибок вы можете использовать error_callback параметр, например: error_callback=lambda x: print(x) , для печати ошибок
  4. Процессы не совместно используют память. Возможно, вы пытаетесь получить доступ к переменной, которая находится в другом процессе, например, в БД. Некоторые соединения с БД не могут быть разделены между процессами.

Надеюсь, что-нибудь из этого поможет!