У меня есть сервер flask, который размещен на Google Dialogflow. Когда мой веб-интерфейс отправляет сообщение в Dialogflow, Dialogflow отправляет сообщение на мой сервер, чтобы сообщить, что сообщение было создано, и ожидает ответа в течение 5 секунд. Если мой сервер не может выполнить этот запрос в течение 5 секунд, он терпит неудачу. Поэтому я создаю очередь задач, чтобы можно было отправить ответ в течение 5 секунд. Ответ, который я отправляю, является триггером события, так что Dialogflow снова отправит сообщение на мой сервер, чтобы проверить состояние подпроцесса. Я заметил, что моя очередь заполнялась, но зависала. Redis всегда работал в пределах Docker, но изначально мои методы Worker не работали. Теперь все работает в пределах Docker.
. Я вижу, что мои задачи переносятся в мою очередь, если я sh помещаю в контейнер Redis команду redis-cli:
127.0.0.1:6379> lrange rq:queue:default 0 -1
1) "7dcc26d1-****-****-****-d32544f18dca"
2) "dc217f00-****-****-****-9a5b455f945b"
3) "d2f93178-****-****-****-b5289d4aacda"
Я также вижу, что у меня определены работники:
127.0.0.1:6379> smembers rq:workers
1) "rq:worker:4bb240********138f4e0a9e27309955"
Обратите внимание, я закомментировал некоторые элементы идентификаторов, так как не был уверен, были ли они каким-либо образом чувствительными.
Методы, которые я использую для проверки этого, очень просты и, безусловно, являются допустимым кодом:
def helloWorld( sleepTime: int) -> str:
time.sleep( sleepTime)
return f'hello world! I slept for {sleepTime=} seconds!'
def queueTest() -> dict:
with Connection( redis.from_url( os.getenv( "REDIS_URL"))):
q = Queue()
sleepTime = random.randrange( 6,10)
job = q.enqueue( helloWorld, sleepTime)
return job.id
Очередь добавляется в другой модуль, поскольку рабочие методы не могут быть определены в том же пространстве имен.
@intents.intent( 'sleepTest')
def sleepTest( agent):
_id = queueTest()
logger.info( f'sleep test, { _id=}')
agent.processId = _id
logger.info( f'sleep test, { agent.processId=}')
agent.eventResponse = True
return
Главное, что делает вышеописанный метод, - это вызвать метод в очередь, добавить идентификатор процесса к данным ответа, которые я передам Dialogflow, а также сообщить Dialogflow, что он должен инициировать последующее событие (логический флаг) один раз снова отправьте сообщение на мой сервер, чтобы проверить состояние моего события.
Я могу видеть из своей записи flask, что Dialogflow действительно отправляет последующие события, как я и ожидал, но никогда не видит задачу comp. leted. Каждый раз, когда он возвращается, видит, что задание не выполнено, ему предлагается повторить проверку с тем же последующим событием. Он делает это так, как я ожидал до разумного предела Dialogflow в 3 раза, прежде чем он сдался. Это ведет себя так, что событие действительно не завершается.
Что мне нужно решить, так это то, что задачи не выполняются.
Для полноты мой docker -compose.yml
version: "3"
services:
userDB:
image: mongo:3.4.23-xenial
ports:
- 27017:27017
volumes:
- ./user-db:/data/db
networks:
- chatbot
client:
build: ./client
ports:
- 8080:80
web:
build: ./server/flask
image: web
container_name: web
restart: always
volumes:
- ./server:/usr/src/app
ports:
- 5000:5000
command: python manage.py run -h 0.0.0.0
environment:
- APP_NAME=Chatbot
env_file:
- ./server/.env
depends_on:
- redis
networks:
- chatbot
worker:
command: python manage.py run_worker
image: web
volumes:
- ./server:/usr/src/app
env_file:
- ./server/.env
depends_on:
- redis
- web
networks:
- chatbot
redis:
image: redis:5.0.7-alpine
networks:
- chatbot
ports:
- 6379:6379
dashboard:
build: ./dashboard
image: dashboard
container_name: dashboard
ports:
- 9181:9181
command: rq-dashboard -H redis
depends_on:
- redis
networks:
chatbot:
driver: bridge
РЕДАКТИРОВАТЬ: Я добавил очень небольшое количество примера кода, чтобы можно было повторить проблему. Пожалуйста, найдите его на следующем репозитории github. Требуется Docker / Python 3,8 https://github.com/PAMSupport/TaskQueue.git