Mar*_*tin 5 python django workflow django-viewflow
我想用ViewFlow库实现以下用例:
由用户启动的特定流程的进程必须在执行芹菜作业之前在队列中等待.每个用户都有这些进程的队列.根据计划或手动触发,允许队列中的下一个进程继续.
我的流中的节点进入命名队列.应用程序中的其他逻辑为每个队列确定何时允许下一个任务继续进行.选择队列中的下一个任务并调用其激活的done()方法.
示例流可能如下所示:
class MyFlow(Flow):
start = flow.Start(...).Next(queue_wait)
queue_wait = QueueWait("myQueue").Next(job)
job = celery.Job(...).Next(end)
end = flow.End()
Run Code Online (Sandbox Code Playgroud)
实施排队的最佳方法是什么?在上面的例子中,我不知道"QueueWait"应该是什么.
我已经阅读了文档和视图流代码,但是我还不清楚是否可以使用内置的Node和Activation类(如func.Function)来完成,或者如果我需要使用自定义类进行扩展.
经过多次实验,我得出了一个可行且简单的解决方案:
from viewflow.flow import base
from viewflow.flow.func import FuncActivation
from viewflow.activation import STATUS
class Queue(base.NextNodeMixin,
base.UndoViewMixin,
base.CancelViewMixin,
base.DetailsViewMixin,
base.Event):
"""
Node that halts the flow and waits in a queue. To process the next waiting task
call the dequeue method, optionally specifying the task owner.
Example placing a job in a queue::
class MyFlow(Flow):
wait = Queue().Next(this.job)
job = celery.Job(send_stuff).Next(this.end)
end = flow.End()
somewhere in the application code:
MyFlow.wait.dequeue()
or:
MyFlow.wait.dequeue(process__myprocess__owner=user)
Queues are logically separated by the task_type, so new queues defined in a
subclass by overriding task_type attribute.
"""
task_type = 'QUEUE'
activation_cls = FuncActivation
def __init__(self, **kwargs):
super(Queue, self).__init__(**kwargs)
def dequeue(self, **kwargs):
"""
Process the next task in the queue by created date/time. kwargs is
used to add task filter arguments, thereby effectively splitting the queue
into subqueues. This could be used to implement per-user queues.
Returns True if task was found and dequeued, False otherwise
"""
filter_kwargs = {'flow_task_type': self.task_type, 'status': STATUS.NEW}
if kwargs is not None:
filter_kwargs.update(kwargs)
task = self.flow_cls.task_cls.objects.filter(**filter_kwargs).order_by('created').first()
if task is not None:
lock = self.flow_cls.lock_impl(self.flow_cls.instance)
with lock(self.flow_cls, task.process_id):
task = self.flow_cls.task_cls._default_manager.get(pk=task.pk)
activation = self.activation_cls()
activation.initialize(self, task)
activation.prepare()
activation.done()
return True
return False
Run Code Online (Sandbox Code Playgroud)
我试图使其尽可能通用,并支持多个命名队列以及子队列的定义,例如每用户队列。
| 归档时间: |
|
| 查看次数: |
500 次 |
| 最近记录: |