【发布时间】:2020-02-29 21:53:32
【问题描述】:
我有一个 Web 服务(Python 3.7、Flask 1.0.2),其工作流程由 3 个步骤组成:
- 第 1 步:将远程计算作业提交到商业排队系统(IBM 的 LSF)
- 第 2 步:每 61 秒轮询一次远程计算作业状态(61 秒,因为缓存了作业状态结果)
- 第 3 步:如果第 2 步返回远程计算作业状态 == “DONE”,则进行数据后处理
远程计算作业的长度是任意的(在秒和天之间),每一步都取决于前一步的完成:
with Connection(redis.from_url(current_app.config['REDIS_URL'])):
q = Queue()
job1 = q.enqueue(step1)
job2 = q.enqueue(step2, depends_on=job1)
job3 = q.enqueue(step3, depends_on=job2)
但是,最终所有工作人员(4 名工作人员)都会进行轮询(4 个客户端请求中的第 2 步),而他们应该继续对其他传入请求进行第 1 步,以及那些已成功通过第 2 步的工作流的第 3 步。
应在每次民意调查后释放工人。他们应该定期返回第 2 步进行下一次轮询(每个作业最多每 61 秒一次),如果远程计算作业轮询未返回“DONE”,则重新排队轮询作业。
此时我开始使用rq-scheduler(因为间隔和重新排队功能听起来很有希望):
with Connection(redis.from_url(current_app.config['REDIS_URL'])):
q = Queue()
s = Scheduler('default')
job1 = q.enqueue(step1, REQ_ID)
job2 = Job.create(step2, (REQ_ID,), depends_on=job1)
job2.meta['interval'] = 61
job2.origin = 'default'
job2.save()
s.enqueue_job(job2)
job3 = q.enqueue(step3, REQ_ID, depends_on=job2)
Job2 被正确创建(包括 depends_on 与 job1 的关系,但 s.enqueue_job() 立即执行它,忽略它与 job1 的关系。(q.enqueue_job() 的函数 doc-string 实际上说它是立即执行...)。
当 job2 放入调度程序而不是队列时,如何在 job1、job2 和 job3 之间创建 depends_on 关系? (或者,我怎样才能将 job2 交给调度程序,而不是立即执行 job2 并等待 job1 完成?)
出于测试目的,步骤如下所示:
def step1():
print(f'*** --> [{datetime.utcnow()}] JOB [ 1 ] STARTED...', flush=True)
time.sleep(20)
print(f' <-- [{datetime.utcnow()}] JOB [ 1 ] FINISHED', flush=True)
return True
def step2():
print(f' --> [{datetime.utcnow()}] POLL JOB [ 2 ] STARTED...', flush=True)
time.sleep(10)
print(f' <-- [{datetime.utcnow()}] POLL JOB [ 2 ] FINISHED', flush=True)
return True
def step3():
print(f' --> [{datetime.utcnow()}] JOB [ 3 ] STARTED...', flush=True)
time.sleep(10)
print(f'*** <-- [{datetime.utcnow()}] JOB [ 3 ] FINISHED', flush=True)
return True
我收到的输出是这样的:
worker_1 | 14:44:57 default: project.server.main.tasks.step1(1) (d40256a2-904f-4ce3-98da-6e49b5d370c9)
worker_2 | 14:44:57 default: project.server.main.tasks.step2(1) (3736909c-f05d-4160-9a76-01bb1b18db58)
worker_2 | --> [2019-11-04 14:44:57.341133] POLL JOB [ 2 ] STARTED...
worker_1 | *** --> [2019-11-04 14:44:57.342142] JOB [ 1 ] STARTED...
...
job2 没有等待 job1 完成...
#requirements.txt
Flask==1.0.2
Flask-Bootstrap==3.3.7.1
Flask-Testing==0.7.1
Flask-WTF==0.14.2
redis==3.3.11
rq==0.13
rq_scheduler==0.9.1
【问题讨论】:
标签: python redis task-queue python-rq