ddeutil-workflow 0.0.29__py3-none-any.whl → 0.0.31__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,7 +29,8 @@ from concurrent.futures import (
29
29
  )
30
30
  from dataclasses import field
31
31
  from datetime import datetime, timedelta
32
- from functools import total_ordering
32
+ from enum import Enum
33
+ from functools import partial, total_ordering
33
34
  from heapq import heappop, heappush
34
35
  from queue import Queue
35
36
  from textwrap import dedent
@@ -53,29 +54,42 @@ from .utils import (
53
54
  cut_id,
54
55
  gen_id,
55
56
  get_dt_now,
56
- wait_a_minute,
57
+ reach_next_minute,
58
+ wait_to_next_minute,
57
59
  )
58
60
 
59
61
  logger = get_logger("ddeutil.workflow")
60
62
 
61
63
  __all__: TupleStr = (
64
+ "Release",
65
+ "ReleaseQueue",
66
+ "ReleaseType",
62
67
  "Workflow",
63
- "WorkflowRelease",
64
- "WorkflowQueue",
65
68
  "WorkflowTask",
66
69
  )
67
70
 
68
71
 
72
+ class ReleaseType(str, Enum):
73
+ """Release Type Enum support the type field on the Release dataclass."""
74
+
75
+ DEFAULT: str = "manual"
76
+ TASK: str = "task"
77
+ POKE: str = "poking"
78
+
79
+
69
80
  @total_ordering
70
- @dataclass(config=ConfigDict(arbitrary_types_allowed=True))
71
- class WorkflowRelease:
72
- """Workflow release Pydantic dataclass object."""
81
+ @dataclass(
82
+ config=ConfigDict(arbitrary_types_allowed=True, use_enum_values=True)
83
+ )
84
+ class Release:
85
+ """Release Pydantic dataclass object that use for represent
86
+ the release data that use with the `workflow.release` method."""
73
87
 
74
88
  date: datetime
75
89
  offset: float
76
90
  end_date: datetime
77
91
  runner: CronRunner
78
- type: str
92
+ type: ReleaseType = field(default=ReleaseType.DEFAULT)
79
93
 
80
94
  def __repr__(self) -> str:
81
95
  return repr(f"{self.date:%Y-%m-%d %H:%M:%S}")
@@ -85,7 +99,7 @@ class WorkflowRelease:
85
99
 
86
100
  @classmethod
87
101
  def from_dt(cls, dt: datetime | str) -> Self:
88
- """Construct WorkflowRelease via datetime object only.
102
+ """Construct Release via datetime object only.
89
103
 
90
104
  :param dt: A datetime object.
91
105
 
@@ -93,16 +107,19 @@ class WorkflowRelease:
93
107
  """
94
108
  if isinstance(dt, str):
95
109
  dt: datetime = datetime.fromisoformat(dt)
110
+ elif not isinstance(dt, datetime):
111
+ raise TypeError(
112
+ "The `from_dt` need argument type be str or datetime only."
113
+ )
96
114
 
97
115
  return cls(
98
116
  date=dt,
99
117
  offset=0,
100
118
  end_date=dt + timedelta(days=1),
101
119
  runner=CronJob("* * * * *").schedule(dt.replace(tzinfo=config.tz)),
102
- type="manual",
103
120
  )
104
121
 
105
- def __eq__(self, other: WorkflowRelease | datetime) -> bool:
122
+ def __eq__(self, other: Release | datetime) -> bool:
106
123
  """Override equal property that will compare only the same type or
107
124
  datetime.
108
125
  """
@@ -112,7 +129,7 @@ class WorkflowRelease:
112
129
  return self.date == other
113
130
  return NotImplemented
114
131
 
115
- def __lt__(self, other: WorkflowRelease | datetime) -> bool:
132
+ def __lt__(self, other: Release | datetime) -> bool:
116
133
  """Override equal property that will compare only the same type or
117
134
  datetime.
118
135
  """
@@ -124,19 +141,19 @@ class WorkflowRelease:
124
141
 
125
142
 
126
143
  @dataclass
127
- class WorkflowQueue:
128
- """Workflow Queue object that is management of WorkflowRelease objects."""
144
+ class ReleaseQueue:
145
+ """Workflow Queue object that is management of Release objects."""
129
146
 
130
- queue: list[WorkflowRelease] = field(default_factory=list)
131
- running: list[WorkflowRelease] = field(default_factory=list)
132
- complete: list[WorkflowRelease] = field(default_factory=list)
147
+ queue: list[Release] = field(default_factory=list)
148
+ running: list[Release] = field(default_factory=list)
149
+ complete: list[Release] = field(default_factory=list)
133
150
 
134
151
  @classmethod
135
152
  def from_list(
136
- cls, queue: list[datetime] | list[WorkflowRelease] | None = None
153
+ cls, queue: list[datetime] | list[Release] | None = None
137
154
  ) -> Self:
138
- """Construct WorkflowQueue object from an input queue value that passing
139
- with list of datetime or list of WorkflowRelease.
155
+ """Construct ReleaseQueue object from an input queue value that passing
156
+ with list of datetime or list of Release.
140
157
 
141
158
  :raise TypeError: If the type of input queue does not valid.
142
159
 
@@ -148,14 +165,14 @@ class WorkflowQueue:
148
165
  if isinstance(queue, list):
149
166
 
150
167
  if all(isinstance(q, datetime) for q in queue):
151
- return cls(queue=[WorkflowRelease.from_dt(q) for q in queue])
168
+ return cls(queue=[Release.from_dt(q) for q in queue])
152
169
 
153
- if all(isinstance(q, WorkflowRelease) for q in queue):
170
+ if all(isinstance(q, Release) for q in queue):
154
171
  return cls(queue=queue)
155
172
 
156
173
  raise TypeError(
157
- "Type of the queue does not valid with WorkflowQueue "
158
- "or list of datetime or list of WorkflowRelease."
174
+ "Type of the queue does not valid with ReleaseQueue "
175
+ "or list of datetime or list of Release."
159
176
  )
160
177
 
161
178
  @property
@@ -167,32 +184,25 @@ class WorkflowQueue:
167
184
  return len(self.queue) > 0
168
185
 
169
186
  @property
170
- def first_queue(self) -> WorkflowRelease:
171
- """Check an input WorkflowRelease object is the first value of the
187
+ def first_queue(self) -> Release:
188
+ """Check an input Release object is the first value of the
172
189
  waiting queue.
173
190
 
174
191
  :rtype: bool
175
192
  """
176
- # NOTE: Old logic to peeking the first release from waiting queue.
177
- #
178
- # first_value: WorkflowRelease = heappop(self.queue)
179
- # heappush(self.queue, first_value)
180
- #
181
- # return first_value
182
- #
183
193
  return self.queue[0]
184
194
 
185
- def check_queue(self, value: WorkflowRelease | datetime) -> bool:
186
- """Check a WorkflowRelease value already exists in list of tracking
195
+ def check_queue(self, value: Release | datetime) -> bool:
196
+ """Check a Release value already exists in list of tracking
187
197
  queues.
188
198
 
189
- :param value: A WorkflowRelease object that want to check it already in
199
+ :param value: A Release object that want to check it already in
190
200
  queues.
191
201
 
192
202
  :rtype: bool
193
203
  """
194
204
  if isinstance(value, datetime):
195
- value = WorkflowRelease.from_dt(value)
205
+ value = Release.from_dt(value)
196
206
 
197
207
  return (
198
208
  (value in self.queue)
@@ -200,13 +210,21 @@ class WorkflowQueue:
200
210
  or (value in self.complete)
201
211
  )
202
212
 
203
- def remove_running(self, value: WorkflowRelease) -> Self:
204
- """Remove WorkflowRelease in the running queue if it exists."""
213
+ def remove_running(self, value: Release) -> Self:
214
+ """Remove Release in the running queue if it exists.
215
+
216
+ :rtype: Self
217
+ """
205
218
  if value in self.running:
206
219
  self.running.remove(value)
207
220
 
208
- def mark_complete(self, value: WorkflowRelease) -> Self:
209
- """Push WorkflowRelease to the complete queue."""
221
+ return self
222
+
223
+ def mark_complete(self, value: Release) -> Self:
224
+ """Push Release to the complete queue.
225
+
226
+ :rtype: Self
227
+ """
210
228
  heappush(self.complete, value)
211
229
 
212
230
  # NOTE: Remove complete queue on workflow that keep more than the
@@ -216,7 +234,6 @@ class WorkflowQueue:
216
234
  )
217
235
 
218
236
  if num_complete_delete > 0:
219
- print(num_complete_delete)
220
237
  for _ in range(num_complete_delete):
221
238
  heappop(self.complete)
222
239
 
@@ -464,14 +481,12 @@ class Workflow(BaseModel):
464
481
 
465
482
  def release(
466
483
  self,
467
- release: datetime | WorkflowRelease,
484
+ release: datetime | Release,
468
485
  params: DictData,
469
486
  *,
470
487
  run_id: str | None = None,
471
488
  log: type[Log] = None,
472
- queue: (
473
- WorkflowQueue | list[datetime] | list[WorkflowRelease] | None
474
- ) = None,
489
+ queue: ReleaseQueue | None = None,
475
490
  override_log_name: str | None = None,
476
491
  ) -> Result:
477
492
  """Release the workflow execution with overriding parameter with the
@@ -481,20 +496,20 @@ class Workflow(BaseModel):
481
496
  This method allow workflow use log object to save the execution
482
497
  result to log destination like file log to the local `/logs` directory.
483
498
 
484
- :Steps:
485
- - Initialize WorkflowQueue and WorkflowRelease if they do not pass.
499
+ Steps:
500
+ - Initialize ReleaseQueue and Release if they do not pass.
486
501
  - Create release data for pass to parameter templating function.
487
502
  - Execute this workflow with mapping release data to its parameters.
488
503
  - Writing result log
489
504
  - Remove this release on the running queue
490
505
  - Push this release to complete queue
491
506
 
492
- :param release: A release datetime or WorkflowRelease object.
507
+ :param release: A release datetime or Release object.
493
508
  :param params: A workflow parameter that pass to execute method.
494
- :param queue: A list of release time that already queue.
509
+ :param queue: A ReleaseQueue that use for mark complete.
495
510
  :param run_id: A workflow running ID for this release.
496
511
  :param log: A log class that want to save the execution result.
497
- :param queue: A WorkflowQueue object.
512
+ :param queue: A ReleaseQueue object.
498
513
  :param override_log_name: An override logging name that use instead
499
514
  the workflow name.
500
515
 
@@ -504,16 +519,17 @@ class Workflow(BaseModel):
504
519
  name: str = override_log_name or self.name
505
520
  run_id: str = run_id or gen_id(name, unique=True)
506
521
  rs_release: Result = Result(run_id=run_id)
507
- rs_release_type: str = "release"
508
522
 
509
- # VALIDATE: Change queue value to WorkflowQueue object.
510
- if queue is None or isinstance(queue, list):
511
- queue: WorkflowQueue = WorkflowQueue.from_list(queue)
523
+ if queue is not None and not isinstance(queue, ReleaseQueue):
524
+ raise TypeError(
525
+ "The queue argument should be ReleaseQueue object only."
526
+ )
512
527
 
513
- # VALIDATE: Change release value to WorkflowRelease object.
528
+ # VALIDATE: Change release value to Release object.
529
+ rs_release_type: str = "release"
514
530
  if isinstance(release, datetime):
515
531
  rs_release_type: str = "datetime"
516
- release: WorkflowRelease = WorkflowRelease.from_dt(release)
532
+ release: Release = Release.from_dt(release)
517
533
 
518
534
  logger.debug(
519
535
  f"({cut_id(run_id)}) [RELEASE]: Start release - {name!r} : "
@@ -542,24 +558,26 @@ class Workflow(BaseModel):
542
558
  )
543
559
 
544
560
  rs.set_parent_run_id(run_id)
545
- rs_log: Log = log.model_validate(
546
- {
547
- "name": name,
548
- "release": release.date,
549
- "type": release.type,
550
- "context": rs.context,
551
- "parent_run_id": rs.parent_run_id,
552
- "run_id": rs.run_id,
553
- }
554
- )
555
561
 
556
562
  # NOTE: Saving execution result to destination of the input log object.
557
563
  logger.debug(f"({cut_id(run_id)}) [LOG]: Writing log: {name!r}.")
558
- rs_log.save(excluded=None)
564
+ (
565
+ log.model_validate(
566
+ {
567
+ "name": name,
568
+ "release": release.date,
569
+ "type": release.type,
570
+ "context": rs.context,
571
+ "parent_run_id": rs.parent_run_id,
572
+ "run_id": rs.run_id,
573
+ }
574
+ ).save(excluded=None)
575
+ )
559
576
 
560
577
  # NOTE: Remove this release from running.
561
- queue.remove_running(release)
562
- queue.mark_complete(release)
578
+ if queue is not None:
579
+ queue.remove_running(release)
580
+ queue.mark_complete(release)
563
581
 
564
582
  # NOTE: Remove the params key from the result context for deduplicate.
565
583
  context: dict[str, Any] = rs.context
@@ -583,13 +601,21 @@ class Workflow(BaseModel):
583
601
  self,
584
602
  offset: float,
585
603
  end_date: datetime,
586
- queue: WorkflowQueue,
604
+ queue: ReleaseQueue,
587
605
  log: type[Log],
588
606
  *,
589
607
  force_run: bool = False,
590
- ) -> WorkflowQueue:
591
- """Generate queue of datetime from the cron runner that initialize from
592
- the on field. with offset value.
608
+ ) -> ReleaseQueue:
609
+ """Generate Release from all on values from the on field and store them
610
+ to the ReleaseQueue object.
611
+
612
+ Steps:
613
+ - For-loop all the on value in the on field.
614
+ - Create Release object from the current date that not reach the end
615
+ date.
616
+ - Check this release do not store on the release queue object.
617
+ Generate the next date if it exists.
618
+ - Push this release to the release queue
593
619
 
594
620
  :param offset: An offset in second unit for time travel.
595
621
  :param end_date: An end datetime object.
@@ -598,7 +624,7 @@ class Workflow(BaseModel):
598
624
  :param force_run: A flag that allow to release workflow if the log with
599
625
  that release was pointed.
600
626
 
601
- :rtype: WorkflowQueue
627
+ :rtype: ReleaseQueue
602
628
  """
603
629
  for on in self.on:
604
630
 
@@ -610,30 +636,30 @@ class Workflow(BaseModel):
610
636
  if runner.date > end_date:
611
637
  continue
612
638
 
613
- workflow_release = WorkflowRelease(
639
+ workflow_release = Release(
614
640
  date=runner.date,
615
641
  offset=offset,
616
642
  end_date=end_date,
617
643
  runner=runner,
618
- type="poking",
644
+ type=ReleaseType.POKE,
619
645
  )
620
646
 
621
647
  while queue.check_queue(workflow_release) or (
622
648
  log.is_pointed(name=self.name, release=workflow_release.date)
623
649
  and not force_run
624
650
  ):
625
- workflow_release = WorkflowRelease(
651
+ workflow_release = Release(
626
652
  date=runner.next,
627
653
  offset=offset,
628
654
  end_date=end_date,
629
655
  runner=runner,
630
- type="poking",
656
+ type=ReleaseType.POKE,
631
657
  )
632
658
 
633
659
  if runner.date > end_date:
634
660
  continue
635
661
 
636
- # NOTE: Push the WorkflowRelease object to queue.
662
+ # NOTE: Push the Release object to queue.
637
663
  heappush(queue.queue, workflow_release)
638
664
 
639
665
  return queue
@@ -656,6 +682,9 @@ class Workflow(BaseModel):
656
682
  This method will observe its schedule that nearing to run with the
657
683
  ``self.release()`` method.
658
684
 
685
+ The limitation of this method is not allow run a date that less
686
+ than the current date.
687
+
659
688
  :param start_date: A start datetime object.
660
689
  :param params: A parameters that want to pass to the release method.
661
690
  :param run_id: A workflow running ID for this poke.
@@ -672,6 +701,12 @@ class Workflow(BaseModel):
672
701
  log: type[Log] = log or get_log()
673
702
  run_id: str = run_id or gen_id(self.name, unique=True)
674
703
 
704
+ # VALIDATE: Check the periods value should gather than 0.
705
+ if periods <= 0:
706
+ raise WorkflowException(
707
+ "The period of poking should be int and grater or equal than 1."
708
+ )
709
+
675
710
  # NOTE: If this workflow does not set the on schedule, it will return
676
711
  # empty result.
677
712
  if len(self.on) == 0:
@@ -681,23 +716,25 @@ class Workflow(BaseModel):
681
716
  )
682
717
  return []
683
718
 
684
- if periods <= 0:
685
- raise WorkflowException(
686
- "The period of poking should be int and grater or equal than 1."
687
- )
719
+ # NOTE: Create the current date that change microsecond to 0
720
+ current_date: datetime = datetime.now(tz=config.tz).replace(
721
+ microsecond=0
722
+ )
688
723
 
689
724
  # NOTE: Create start_date and offset variables.
690
- current_date: datetime = datetime.now(tz=config.tz)
691
-
692
725
  if start_date and start_date <= current_date:
693
- start_date = start_date.replace(tzinfo=config.tz)
726
+ start_date = start_date.replace(tzinfo=config.tz).replace(
727
+ microsecond=0
728
+ )
694
729
  offset: float = (current_date - start_date).total_seconds()
695
730
  else:
731
+ # NOTE: Force change start date if it gathers than the current date,
732
+ # or it does not pass to this method.
696
733
  start_date: datetime = current_date
697
734
  offset: float = 0
698
735
 
699
- # NOTE: End date is using to stop generate queue with an input periods
700
- # value.
736
+ # NOTE: The end date is using to stop generate queue with an input
737
+ # periods value.
701
738
  end_date: datetime = start_date + timedelta(minutes=periods)
702
739
 
703
740
  logger.info(
@@ -708,18 +745,18 @@ class Workflow(BaseModel):
708
745
  params: DictData = {} if params is None else params
709
746
  results: list[Result] = []
710
747
 
711
- # NOTE: Create empty WorkflowQueue object.
712
- wf_queue: WorkflowQueue = WorkflowQueue()
748
+ # NOTE: Create empty ReleaseQueue object.
749
+ q: ReleaseQueue = ReleaseQueue()
713
750
 
714
- # NOTE: Make queue to the workflow queue object.
715
- self.queue(
716
- offset,
717
- end_date=end_date,
718
- queue=wf_queue,
719
- log=log,
720
- force_run=force_run,
751
+ # NOTE: Create reusable partial function and add Release to the release
752
+ # queue object.
753
+ partial_queue = partial(
754
+ self.queue, offset, end_date, log=log, force_run=force_run
721
755
  )
722
- if not wf_queue.is_queued:
756
+ partial_queue(q)
757
+
758
+ # NOTE: Return the empty result if it does not have any Release.
759
+ if not q.is_queued:
723
760
  logger.info(
724
761
  f"({cut_id(run_id)}) [POKING]: {self.name!r} does not have "
725
762
  f"any queue."
@@ -735,34 +772,27 @@ class Workflow(BaseModel):
735
772
 
736
773
  futures: list[Future] = []
737
774
 
738
- while wf_queue.is_queued:
775
+ while q.is_queued:
739
776
 
740
- # NOTE: Pop the latest WorkflowRelease object from queue.
741
- release: WorkflowRelease = heappop(wf_queue.queue)
777
+ # NOTE: Pop the latest Release object from the release queue.
778
+ release: Release = heappop(q.queue)
742
779
 
743
- if (
744
- release.date - get_dt_now(tz=config.tz, offset=offset)
745
- ).total_seconds() > 60:
780
+ if reach_next_minute(release.date, tz=config.tz, offset=offset):
746
781
  logger.debug(
747
- f"({cut_id(run_id)}) [POKING]: Wait because the latest "
748
- f"release has diff time more than 60 seconds ..."
782
+ f"({cut_id(run_id)}) [POKING]: The latest release, "
783
+ f"{release.date:%Y-%m-%d %H:%M:%S}, is not able to run "
784
+ f"on this minute"
749
785
  )
750
- heappush(wf_queue.queue, release)
751
- wait_a_minute(get_dt_now(tz=config.tz, offset=offset))
786
+ heappush(q.queue, release)
787
+ wait_to_next_minute(get_dt_now(tz=config.tz, offset=offset))
752
788
 
753
789
  # WARNING: I already call queue poking again because issue
754
790
  # about the every minute crontab.
755
- self.queue(
756
- offset,
757
- end_date,
758
- queue=wf_queue,
759
- log=log,
760
- force_run=force_run,
761
- )
791
+ partial_queue(q)
762
792
  continue
763
793
 
764
- # NOTE: Push the latest WorkflowRelease to the running queue.
765
- heappush(wf_queue.running, release)
794
+ # NOTE: Push the latest Release to the running queue.
795
+ heappush(q.running, release)
766
796
 
767
797
  futures.append(
768
798
  executor.submit(
@@ -770,17 +800,11 @@ class Workflow(BaseModel):
770
800
  release=release,
771
801
  params=params,
772
802
  log=log,
773
- queue=wf_queue,
803
+ queue=q,
774
804
  )
775
805
  )
776
806
 
777
- self.queue(
778
- offset,
779
- end_date,
780
- queue=wf_queue,
781
- log=log,
782
- force_run=force_run,
783
- )
807
+ partial_queue(q)
784
808
 
785
809
  # WARNING: This poking method does not allow to use fail-fast
786
810
  # logic to catching parallel execution result.
@@ -1127,6 +1151,9 @@ class WorkflowTask:
1127
1151
 
1128
1152
  This dataclass object is mapping 1-to-1 with workflow and cron runner
1129
1153
  objects.
1154
+
1155
+ This dataclass has the release method for itself.
1156
+
1130
1157
  """
1131
1158
 
1132
1159
  alias: str
@@ -1136,25 +1163,34 @@ class WorkflowTask:
1136
1163
 
1137
1164
  def release(
1138
1165
  self,
1139
- release: datetime | WorkflowRelease | None = None,
1166
+ release: datetime | Release | None = None,
1140
1167
  run_id: str | None = None,
1141
1168
  log: type[Log] = None,
1142
- queue: (
1143
- WorkflowQueue | list[datetime] | list[WorkflowRelease] | None
1144
- ) = None,
1169
+ queue: ReleaseQueue | None = None,
1145
1170
  ) -> Result:
1146
1171
  """Release the workflow task data.
1147
1172
 
1148
- :param release: A release datetime or WorkflowRelease object.
1173
+ :param release: A release datetime or Release object.
1149
1174
  :param run_id: A workflow running ID for this release.
1150
1175
  :param log: A log class that want to save the execution result.
1151
- :param queue: A WorkflowQueue object.
1176
+ :param queue: A ReleaseQueue object that use to mark complete.
1152
1177
 
1153
1178
  :rtype: Result
1154
1179
  """
1155
1180
  log: type[Log] = log or get_log()
1156
1181
 
1157
1182
  if release is None:
1183
+
1184
+ if queue is None:
1185
+ raise ValueError(
1186
+ "If pass None release value, you should to pass the queue"
1187
+ "for generate this release."
1188
+ )
1189
+ elif not isinstance(queue, ReleaseQueue):
1190
+ raise TypeError(
1191
+ "The queue argument should be ReleaseQueue object only."
1192
+ )
1193
+
1158
1194
  if queue.check_queue(self.runner.date):
1159
1195
  release = self.runner.next
1160
1196
 
@@ -1163,6 +1199,7 @@ class WorkflowTask:
1163
1199
  else:
1164
1200
  release = self.runner.date
1165
1201
 
1202
+ # NOTE: Call the workflow release method.
1166
1203
  return self.workflow.release(
1167
1204
  release=release,
1168
1205
  params=self.values,
@@ -1175,12 +1212,13 @@ class WorkflowTask:
1175
1212
  def queue(
1176
1213
  self,
1177
1214
  end_date: datetime,
1178
- queue: WorkflowQueue,
1215
+ queue: ReleaseQueue,
1179
1216
  log: type[Log],
1180
1217
  *,
1181
1218
  force_run: bool = False,
1182
- ):
1183
- """Generate WorkflowRelease to WorkflowQueue object.
1219
+ ) -> ReleaseQueue:
1220
+ """Generate Release from the runner field and store it to the
1221
+ ReleaseQueue object.
1184
1222
 
1185
1223
  :param end_date: An end datetime object.
1186
1224
  :param queue: A workflow queue object.
@@ -1188,35 +1226,35 @@ class WorkflowTask:
1188
1226
  :param force_run: A flag that allow to release workflow if the log with
1189
1227
  that release was pointed.
1190
1228
 
1191
- :rtype: WorkflowQueue
1229
+ :rtype: ReleaseQueue
1192
1230
  """
1193
1231
  if self.runner.date > end_date:
1194
1232
  return queue
1195
1233
 
1196
- workflow_release = WorkflowRelease(
1234
+ workflow_release = Release(
1197
1235
  date=self.runner.date,
1198
1236
  offset=0,
1199
1237
  end_date=end_date,
1200
1238
  runner=self.runner,
1201
- type="task",
1239
+ type=ReleaseType.TASK,
1202
1240
  )
1203
1241
 
1204
1242
  while queue.check_queue(workflow_release) or (
1205
1243
  log.is_pointed(name=self.alias, release=workflow_release.date)
1206
1244
  and not force_run
1207
1245
  ):
1208
- workflow_release = WorkflowRelease(
1246
+ workflow_release = Release(
1209
1247
  date=self.runner.next,
1210
1248
  offset=0,
1211
1249
  end_date=end_date,
1212
1250
  runner=self.runner,
1213
- type="task",
1251
+ type=ReleaseType.TASK,
1214
1252
  )
1215
1253
 
1216
1254
  if self.runner.date > end_date:
1217
1255
  return queue
1218
1256
 
1219
- # NOTE: Push the WorkflowRelease object to queue.
1257
+ # NOTE: Push the Release object to queue.
1220
1258
  heappush(queue.queue, workflow_release)
1221
1259
 
1222
1260
  return queue