Вызов API в задаче Celery никогда не возвращается

Я хочу получить ценность от web3.eth.getTransactionCount. Просто зависает. Эта функция отлично работает в другом месте (обычное приложение, консоль).

Чтобы воссоздать это поведение, просто создайте новую папку, добавьте эти 3 файла в папку и внутри этой папки запустите docker-compose up. * Обратите внимание, что учетные данные infura безопасны для использования.

dockerfile

FROM python:3.7
WORKDIR /usr/src/app
RUN pip install flask celery[redis] web3

docker-compose.yml

version: "3"
services:
  redis:
    image: redis:5.0.7
    container_name: redis
    ports:
      - "6379:6379"
  myapp:
    build: .
    container_name: myapp
    ports:
      - "5000:5000"
    volumes:
      - .:/usr/src/app
    environment:
      - FLASK_ENV=development
      - WEB3_INFURA_PROJECT_ID=1cc71ab02b99475b8a3172b6a790c2f8
      - WEB3_INFURA_API_SECRET=6a343124ed8e4a6f9b36d28c50ad65ca
    entrypoint: |
      bash -c "python /usr/src/app/app.py"
  celery:
    build: .
    container_name: celery
    volumes:
      - .:/usr/src/app
    environment:
      - WEB3_INFURA_PROJECT_ID=1cc71ab02b99475b8a3172b6a790c2f8
      - WEB3_INFURA_API_SECRET=6a343124ed8e4a6f9b36d28c50ad65ca
    command: celery worker -A app.client -l info

app.py

from flask import Flask
from web3.auto.infura.rinkeby import w3 as web3
from celery import Celery

app = Flask(__name__)
client = Celery(app.name, broker='redis://redis:6379', backend='redis://redis:6379')

@client.task
def never_return():
    print('start')  # this is printed
    nonce = web3.eth.getTransactionCount('0x51cDD4A883144F01Bf0753b6189f3A034866465f')
    print('nonce', nonce)  # this is never printed

@app.route('/')
def index():
    never_return.apply_async()
    return "hello celery"

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

Я нашел здесь только 1 похожий неразрешенный пост: вызов Google Cloud API в задаче Celery никогда не возвращается

Кажется, что-то странное происходит при вызове запроса из другой библиотеки в задаче Celery. Все работает нормально, когда я пытался отправлять почтовые запросы, используяrequest. К сожалению, я не знаю, как обойти эту проблему с помощью этогоrequest библиотека.

Любые предложения приветствуются.

1 ответ

Решение

Мне кажется, что эта проблема как-то связана с веб-сокетами. поэтому я попытался переключить его на HTTP. и это работает.

вот модифицированный app.py

from flask import Flask
from web3 import Web3
from celery import Celery
from web3.middleware import geth_poa_middleware
import os

app = Flask(__name__)
client = Celery(app.name, broker='redis://redis:6379', backend='redis://redis:6379')

@client.task
def never_return():
    w3 = Web3(Web3.HTTPProvider(f"https://rinkeby.infura.io/v3/{os.getenv('WEB3_INFURA_PROJECT_ID')}", request_kwargs={'timeout': 60}))
    w3.middleware_onion.inject(geth_poa_middleware, layer=0)
    print('started')
    l = w3.eth.getBlock('latest')
    print(f'block number: {l}')
    print('finished ok')

@app.route('/')
def index():
    never_return.apply_async()
    return f"hello celery"

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')
Другие вопросы по тегам