diff --git a/tests/test_activation.py b/tests/test_activation.py index c2bab42e..f298acc9 100644 --- a/tests/test_activation.py +++ b/tests/test_activation.py @@ -1,6 +1,6 @@ from django.test import TestCase -from viewflow import activation, flow +from viewflow import activation, flow, lock from viewflow.activation import STATUS from viewflow.compat import mock @@ -16,6 +16,7 @@ def active_tasks(self): return [] def save(self): + self.pk = 1 return ProcessStub._default_manager.get.return_value = ProcessStub() @@ -34,6 +35,7 @@ def leading(self): return Task.objects.none() def save(self): + self.pk = 1 return class UserStub(object): @@ -42,6 +44,7 @@ class UserStub(object): def init_node(self, node): class FlowStub(object): process_cls = Test.ProcessStub + lock_impl = staticmethod(lock.no_lock) task_cls = Test.TaskStub instance = None diff --git a/tests/test_flow_func.py b/tests/test_flow_func.py index cc294af2..cf529d06 100644 --- a/tests/test_flow_func.py +++ b/tests/test_flow_func.py @@ -178,6 +178,7 @@ def active_tasks(self): return [] def save(self): + self.pk = 1 return @@ -197,6 +198,7 @@ def leading(self): return Task.objects.none() def save(self): + self.pk = 1 return diff --git a/viewflow/activation.py b/viewflow/activation.py index bbef4293..802abffa 100644 --- a/viewflow/activation.py +++ b/viewflow/activation.py @@ -212,6 +212,7 @@ class StartActivation(Activation): @Activation.status.super() def initialize(self, flow_task, task): + self.lock = None self.flow_task, self.flow_cls = flow_task, flow_task.flow_cls if task: @@ -249,6 +250,10 @@ def done(self): self.process.save() + lock_impl = self.flow_cls.lock_impl(self.flow_cls.instance) + self.lock = lock_impl(self.flow_cls, self.process.pk) + self.lock.__enter__() + self.task.process = self.process self.task.finished = now() self.task.save() diff --git a/viewflow/decorators.py b/viewflow/decorators.py index 051e3625..e5bb8833 100644 --- a/viewflow/decorators.py +++ b/viewflow/decorators.py @@ -1,3 +1,4 @@ +import sys import traceback import functools @@ -10,9 +11,13 @@ def flow_start_func(func): @functools.wraps(func) def _wrapper(flow_task, *args, **kwargs): - activation = flow_task.activation_cls() - activation.initialize(flow_task, None) - return func(activation, *args, **kwargs) + try: + activation = flow_task.activation_cls() + activation.initialize(flow_task, None) + return func(activation, *args, **kwargs) + finally: + if activation.lock: + activation.lock.__exit__(*sys.exc_info()) return _wrapper @@ -102,9 +107,13 @@ def _wrapper(*args, **kwargs): def flow_start_signal(handler): @functools.wraps(handler) def _wrapper(sender, flow_task=None, **signal_kwargs): - activation = flow_task.activation_cls() - activation.initialize(flow_task, None) - return handler(sender=sender, activation=activation, **signal_kwargs) + try: + activation = flow_task.activation_cls() + activation.initialize(flow_task, None) + return handler(sender=sender, activation=activation, **signal_kwargs) + finally: + if activation.lock: + activation.lock.__exit__(*sys.exc_info()) return _wrapper @@ -136,14 +145,17 @@ def flow_start_view(view): @functools.wraps(view) def _wrapper(request, flow_cls, flow_task, **kwargs): + try: activation = flow_task.activation_cls() activation.initialize(flow_task, None) request.activation = activation request.process = activation.process request.task = activation.task - return view(request, **kwargs) + finally: + if activation.lock: + activation.lock.__exit__(*sys.exc_info()) return _wrapper