diff options
Diffstat (limited to 'stator')
-rw-r--r-- | stator/graph.py | 6 | ||||
-rw-r--r-- | stator/models.py | 28 |
2 files changed, 26 insertions, 8 deletions
diff --git a/stator/graph.py b/stator/graph.py index 424ea49..5c71d4a 100644 --- a/stator/graph.py +++ b/stator/graph.py @@ -87,10 +87,14 @@ class State: try_interval: Optional[float] = None, handler_name: Optional[str] = None, externally_progressed: bool = False, + attempt_immediately: bool = True, + force_initial: bool = False, ): self.try_interval = try_interval self.handler_name = handler_name self.externally_progressed = externally_progressed + self.attempt_immediately = attempt_immediately + self.force_initial = force_initial self.parents: Set["State"] = set() self.children: Set["State"] = set() @@ -121,7 +125,7 @@ class State: @property def initial(self): - return not self.parents + return self.force_initial or (not self.parents) @property def terminal(self): diff --git a/stator/models.py b/stator/models.py index bbff395..5257ac9 100644 --- a/stator/models.py +++ b/stator/models.py @@ -74,6 +74,10 @@ class StatorModel(models.Model): def state_graph(cls) -> Type[StateGraph]: return cls._meta.get_field("state").graph + @property + def state_age(self) -> int: + return (timezone.now() - self.state_changed).total_seconds() + @classmethod async def atransition_schedule_due(cls, now=None) -> models.QuerySet: """ @@ -184,13 +188,23 @@ class StatorModel(models.Model): state = state.name if state not in self.state_graph.states: raise ValueError(f"Invalid state {state}") - self.__class__.objects.filter(pk=self.pk).update( - state=state, - state_changed=timezone.now(), - state_attempted=None, - state_locked_until=None, - state_ready=True, - ) + # See if it's ready immediately (if not, delay until first try_interval) + if self.state_graph.states[state].attempt_immediately: + self.__class__.objects.filter(pk=self.pk).update( + state=state, + state_changed=timezone.now(), + state_attempted=None, + state_locked_until=None, + state_ready=True, + ) + else: + self.__class__.objects.filter(pk=self.pk).update( + state=state, + state_changed=timezone.now(), + state_attempted=timezone.now(), + state_locked_until=None, + state_ready=False, + ) atransition_perform = sync_to_async(transition_perform) |