durabletask 0.3.0__py3-none-any.whl → 0.4.0__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.
Potentially problematic release.
This version of durabletask might be problematic. Click here for more details.
- durabletask/__init__.py +2 -2
- durabletask/client.py +8 -3
- durabletask/internal/exceptions.py +7 -0
- durabletask/internal/helpers.py +12 -6
- durabletask/internal/orchestrator_service_pb2.py +243 -186
- durabletask/internal/orchestrator_service_pb2.pyi +305 -51
- durabletask/internal/orchestrator_service_pb2_grpc.py +510 -88
- durabletask/task.py +21 -2
- durabletask/worker.py +158 -7
- {durabletask-0.3.0.dist-info → durabletask-0.4.0.dist-info}/METADATA +5 -3
- durabletask-0.4.0.dist-info/RECORD +16 -0
- durabletask-0.3.0.dist-info/RECORD +0 -15
- {durabletask-0.3.0.dist-info → durabletask-0.4.0.dist-info}/WHEEL +0 -0
- {durabletask-0.3.0.dist-info → durabletask-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {durabletask-0.3.0.dist-info → durabletask-0.4.0.dist-info}/top_level.txt +0 -0
durabletask/task.py
CHANGED
|
@@ -35,6 +35,21 @@ class OrchestrationContext(ABC):
|
|
|
35
35
|
"""
|
|
36
36
|
pass
|
|
37
37
|
|
|
38
|
+
@property
|
|
39
|
+
@abstractmethod
|
|
40
|
+
def version(self) -> Optional[str]:
|
|
41
|
+
"""Get the version of the orchestration instance.
|
|
42
|
+
|
|
43
|
+
This version is set when the orchestration is scheduled and can be used
|
|
44
|
+
to determine which version of the orchestrator function is being executed.
|
|
45
|
+
|
|
46
|
+
Returns
|
|
47
|
+
-------
|
|
48
|
+
Optional[str]
|
|
49
|
+
The version of the orchestration instance, or None if not set.
|
|
50
|
+
"""
|
|
51
|
+
pass
|
|
52
|
+
|
|
38
53
|
@property
|
|
39
54
|
@abstractmethod
|
|
40
55
|
def current_utc_datetime(self) -> datetime:
|
|
@@ -100,7 +115,8 @@ class OrchestrationContext(ABC):
|
|
|
100
115
|
@abstractmethod
|
|
101
116
|
def call_activity(self, activity: Union[Activity[TInput, TOutput], str], *,
|
|
102
117
|
input: Optional[TInput] = None,
|
|
103
|
-
retry_policy: Optional[RetryPolicy] = None
|
|
118
|
+
retry_policy: Optional[RetryPolicy] = None,
|
|
119
|
+
tags: Optional[dict[str, str]] = None) -> Task[TOutput]:
|
|
104
120
|
"""Schedule an activity for execution.
|
|
105
121
|
|
|
106
122
|
Parameters
|
|
@@ -111,6 +127,8 @@ class OrchestrationContext(ABC):
|
|
|
111
127
|
The JSON-serializable input (or None) to pass to the activity.
|
|
112
128
|
retry_policy: Optional[RetryPolicy]
|
|
113
129
|
The retry policy to use for this activity call.
|
|
130
|
+
tags: Optional[dict[str, str]]
|
|
131
|
+
Optional tags to associate with the activity invocation.
|
|
114
132
|
|
|
115
133
|
Returns
|
|
116
134
|
-------
|
|
@@ -123,7 +141,8 @@ class OrchestrationContext(ABC):
|
|
|
123
141
|
def call_sub_orchestrator(self, orchestrator: Orchestrator[TInput, TOutput], *,
|
|
124
142
|
input: Optional[TInput] = None,
|
|
125
143
|
instance_id: Optional[str] = None,
|
|
126
|
-
retry_policy: Optional[RetryPolicy] = None
|
|
144
|
+
retry_policy: Optional[RetryPolicy] = None,
|
|
145
|
+
version: Optional[str] = None) -> Task[TOutput]:
|
|
127
146
|
"""Schedule sub-orchestrator function for execution.
|
|
128
147
|
|
|
129
148
|
Parameters
|
durabletask/worker.py
CHANGED
|
@@ -10,12 +10,15 @@ from concurrent.futures import ThreadPoolExecutor
|
|
|
10
10
|
from datetime import datetime, timedelta
|
|
11
11
|
from threading import Event, Thread
|
|
12
12
|
from types import GeneratorType
|
|
13
|
+
from enum import Enum
|
|
13
14
|
from typing import Any, Generator, Optional, Sequence, TypeVar, Union
|
|
15
|
+
from packaging.version import InvalidVersion, parse
|
|
14
16
|
|
|
15
17
|
import grpc
|
|
16
18
|
from google.protobuf import empty_pb2
|
|
17
19
|
|
|
18
20
|
import durabletask.internal.helpers as ph
|
|
21
|
+
import durabletask.internal.exceptions as pe
|
|
19
22
|
import durabletask.internal.orchestrator_service_pb2 as pb
|
|
20
23
|
import durabletask.internal.orchestrator_service_pb2_grpc as stubs
|
|
21
24
|
import durabletask.internal.shared as shared
|
|
@@ -72,9 +75,56 @@ class ConcurrencyOptions:
|
|
|
72
75
|
)
|
|
73
76
|
|
|
74
77
|
|
|
78
|
+
class VersionMatchStrategy(Enum):
|
|
79
|
+
"""Enumeration for version matching strategies."""
|
|
80
|
+
|
|
81
|
+
NONE = 1
|
|
82
|
+
STRICT = 2
|
|
83
|
+
CURRENT_OR_OLDER = 3
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class VersionFailureStrategy(Enum):
|
|
87
|
+
"""Enumeration for version failure strategies."""
|
|
88
|
+
|
|
89
|
+
REJECT = 1
|
|
90
|
+
FAIL = 2
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class VersioningOptions:
|
|
94
|
+
"""Configuration options for orchestrator and activity versioning.
|
|
95
|
+
|
|
96
|
+
This class provides options to control how versioning is handled for orchestrators
|
|
97
|
+
and activities, including whether to use the default version and how to compare versions.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
version: Optional[str] = None
|
|
101
|
+
default_version: Optional[str] = None
|
|
102
|
+
match_strategy: Optional[VersionMatchStrategy] = None
|
|
103
|
+
failure_strategy: Optional[VersionFailureStrategy] = None
|
|
104
|
+
|
|
105
|
+
def __init__(self, version: Optional[str] = None,
|
|
106
|
+
default_version: Optional[str] = None,
|
|
107
|
+
match_strategy: Optional[VersionMatchStrategy] = None,
|
|
108
|
+
failure_strategy: Optional[VersionFailureStrategy] = None
|
|
109
|
+
):
|
|
110
|
+
"""Initialize versioning options.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
version: The version of orchestrations that the worker can work on.
|
|
114
|
+
default_version: The default version that will be used for starting new orchestrations.
|
|
115
|
+
match_strategy: The versioning strategy for the Durable Task worker.
|
|
116
|
+
failure_strategy: The versioning failure strategy for the Durable Task worker.
|
|
117
|
+
"""
|
|
118
|
+
self.version = version
|
|
119
|
+
self.default_version = default_version
|
|
120
|
+
self.match_strategy = match_strategy
|
|
121
|
+
self.failure_strategy = failure_strategy
|
|
122
|
+
|
|
123
|
+
|
|
75
124
|
class _Registry:
|
|
76
125
|
orchestrators: dict[str, task.Orchestrator]
|
|
77
126
|
activities: dict[str, task.Activity]
|
|
127
|
+
versioning: Optional[VersioningOptions] = None
|
|
78
128
|
|
|
79
129
|
def __init__(self):
|
|
80
130
|
self.orchestrators = {}
|
|
@@ -279,6 +329,12 @@ class TaskHubGrpcWorker:
|
|
|
279
329
|
)
|
|
280
330
|
return self._registry.add_activity(fn)
|
|
281
331
|
|
|
332
|
+
def use_versioning(self, version: VersioningOptions) -> None:
|
|
333
|
+
"""Initializes versioning options for sub-orchestrators and activities."""
|
|
334
|
+
if self._is_running:
|
|
335
|
+
raise RuntimeError("Cannot set default version while the worker is running.")
|
|
336
|
+
self._registry.versioning = version
|
|
337
|
+
|
|
282
338
|
def start(self):
|
|
283
339
|
"""Starts the worker on a background thread and begins listening for work items."""
|
|
284
340
|
if self._is_running:
|
|
@@ -513,6 +569,16 @@ class TaskHubGrpcWorker:
|
|
|
513
569
|
customStatus=ph.get_string_value(result.encoded_custom_status),
|
|
514
570
|
completionToken=completionToken,
|
|
515
571
|
)
|
|
572
|
+
except pe.AbandonOrchestrationError:
|
|
573
|
+
self._logger.info(
|
|
574
|
+
f"Abandoning orchestration. InstanceId = '{req.instanceId}'. Completion token = '{completionToken}'"
|
|
575
|
+
)
|
|
576
|
+
stub.AbandonTaskOrchestratorWorkItem(
|
|
577
|
+
pb.AbandonOrchestrationTaskRequest(
|
|
578
|
+
completionToken=completionToken
|
|
579
|
+
)
|
|
580
|
+
)
|
|
581
|
+
return
|
|
516
582
|
except Exception as ex:
|
|
517
583
|
self._logger.exception(
|
|
518
584
|
f"An error occurred while trying to execute instance '{req.instanceId}': {ex}"
|
|
@@ -574,7 +640,7 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
574
640
|
_generator: Optional[Generator[task.Task, Any, Any]]
|
|
575
641
|
_previous_task: Optional[task.Task]
|
|
576
642
|
|
|
577
|
-
def __init__(self, instance_id: str):
|
|
643
|
+
def __init__(self, instance_id: str, registry: _Registry):
|
|
578
644
|
self._generator = None
|
|
579
645
|
self._is_replaying = True
|
|
580
646
|
self._is_complete = False
|
|
@@ -584,6 +650,8 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
584
650
|
self._sequence_number = 0
|
|
585
651
|
self._current_utc_datetime = datetime(1000, 1, 1)
|
|
586
652
|
self._instance_id = instance_id
|
|
653
|
+
self._registry = registry
|
|
654
|
+
self._version: Optional[str] = None
|
|
587
655
|
self._completion_status: Optional[pb.OrchestrationStatus] = None
|
|
588
656
|
self._received_events: dict[str, list[Any]] = {}
|
|
589
657
|
self._pending_events: dict[str, list[task.CompletableTask]] = {}
|
|
@@ -646,7 +714,7 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
646
714
|
)
|
|
647
715
|
self._pending_actions[action.id] = action
|
|
648
716
|
|
|
649
|
-
def set_failed(self, ex: Exception):
|
|
717
|
+
def set_failed(self, ex: Union[Exception, pb.TaskFailureDetails]):
|
|
650
718
|
if self._is_complete:
|
|
651
719
|
return
|
|
652
720
|
|
|
@@ -658,7 +726,7 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
658
726
|
self.next_sequence_number(),
|
|
659
727
|
pb.ORCHESTRATION_STATUS_FAILED,
|
|
660
728
|
None,
|
|
661
|
-
ph.new_failure_details(ex),
|
|
729
|
+
ph.new_failure_details(ex) if isinstance(ex, Exception) else ex,
|
|
662
730
|
)
|
|
663
731
|
self._pending_actions[action.id] = action
|
|
664
732
|
|
|
@@ -709,6 +777,10 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
709
777
|
def instance_id(self) -> str:
|
|
710
778
|
return self._instance_id
|
|
711
779
|
|
|
780
|
+
@property
|
|
781
|
+
def version(self) -> Optional[str]:
|
|
782
|
+
return self._version
|
|
783
|
+
|
|
712
784
|
@property
|
|
713
785
|
def current_utc_datetime(self) -> datetime:
|
|
714
786
|
return self._current_utc_datetime
|
|
@@ -752,11 +824,12 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
752
824
|
*,
|
|
753
825
|
input: Optional[TInput] = None,
|
|
754
826
|
retry_policy: Optional[task.RetryPolicy] = None,
|
|
827
|
+
tags: Optional[dict[str, str]] = None,
|
|
755
828
|
) -> task.Task[TOutput]:
|
|
756
829
|
id = self.next_sequence_number()
|
|
757
830
|
|
|
758
831
|
self.call_activity_function_helper(
|
|
759
|
-
id, activity, input=input, retry_policy=retry_policy, is_sub_orch=False
|
|
832
|
+
id, activity, input=input, retry_policy=retry_policy, is_sub_orch=False, tags=tags
|
|
760
833
|
)
|
|
761
834
|
return self._pending_tasks.get(id, task.CompletableTask())
|
|
762
835
|
|
|
@@ -767,9 +840,12 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
767
840
|
input: Optional[TInput] = None,
|
|
768
841
|
instance_id: Optional[str] = None,
|
|
769
842
|
retry_policy: Optional[task.RetryPolicy] = None,
|
|
843
|
+
version: Optional[str] = None,
|
|
770
844
|
) -> task.Task[TOutput]:
|
|
771
845
|
id = self.next_sequence_number()
|
|
772
846
|
orchestrator_name = task.get_name(orchestrator)
|
|
847
|
+
default_version = self._registry.versioning.default_version if self._registry.versioning else None
|
|
848
|
+
orchestrator_version = version if version else default_version
|
|
773
849
|
self.call_activity_function_helper(
|
|
774
850
|
id,
|
|
775
851
|
orchestrator_name,
|
|
@@ -777,6 +853,7 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
777
853
|
retry_policy=retry_policy,
|
|
778
854
|
is_sub_orch=True,
|
|
779
855
|
instance_id=instance_id,
|
|
856
|
+
version=orchestrator_version
|
|
780
857
|
)
|
|
781
858
|
return self._pending_tasks.get(id, task.CompletableTask())
|
|
782
859
|
|
|
@@ -787,9 +864,11 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
787
864
|
*,
|
|
788
865
|
input: Optional[TInput] = None,
|
|
789
866
|
retry_policy: Optional[task.RetryPolicy] = None,
|
|
867
|
+
tags: Optional[dict[str, str]] = None,
|
|
790
868
|
is_sub_orch: bool = False,
|
|
791
869
|
instance_id: Optional[str] = None,
|
|
792
870
|
fn_task: Optional[task.CompletableTask[TOutput]] = None,
|
|
871
|
+
version: Optional[str] = None,
|
|
793
872
|
):
|
|
794
873
|
if id is None:
|
|
795
874
|
id = self.next_sequence_number()
|
|
@@ -806,7 +885,7 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
806
885
|
if isinstance(activity_function, str)
|
|
807
886
|
else task.get_name(activity_function)
|
|
808
887
|
)
|
|
809
|
-
action = ph.new_schedule_task_action(id, name, encoded_input)
|
|
888
|
+
action = ph.new_schedule_task_action(id, name, encoded_input, tags)
|
|
810
889
|
else:
|
|
811
890
|
if instance_id is None:
|
|
812
891
|
# Create a deteministic instance ID based on the parent instance ID
|
|
@@ -814,7 +893,7 @@ class _RuntimeOrchestrationContext(task.OrchestrationContext):
|
|
|
814
893
|
if not isinstance(activity_function, str):
|
|
815
894
|
raise ValueError("Orchestrator function name must be a string")
|
|
816
895
|
action = ph.new_create_sub_orchestration_action(
|
|
817
|
-
id, activity_function, instance_id, encoded_input
|
|
896
|
+
id, activity_function, instance_id, encoded_input, version
|
|
818
897
|
)
|
|
819
898
|
self._pending_actions[id] = action
|
|
820
899
|
|
|
@@ -890,7 +969,8 @@ class _OrchestrationExecutor:
|
|
|
890
969
|
"The new history event list must have at least one event in it."
|
|
891
970
|
)
|
|
892
971
|
|
|
893
|
-
ctx = _RuntimeOrchestrationContext(instance_id)
|
|
972
|
+
ctx = _RuntimeOrchestrationContext(instance_id, self._registry)
|
|
973
|
+
version_failure = None
|
|
894
974
|
try:
|
|
895
975
|
# Rebuild local state by replaying old history into the orchestrator function
|
|
896
976
|
self._logger.debug(
|
|
@@ -900,6 +980,23 @@ class _OrchestrationExecutor:
|
|
|
900
980
|
for old_event in old_events:
|
|
901
981
|
self.process_event(ctx, old_event)
|
|
902
982
|
|
|
983
|
+
# Process versioning if applicable
|
|
984
|
+
execution_started_events = [e.executionStarted for e in old_events if e.HasField("executionStarted")]
|
|
985
|
+
# We only check versioning if there are executionStarted events - otherwise, on the first replay when
|
|
986
|
+
# ctx.version will be Null, we may invalidate orchestrations early depending on the versioning strategy.
|
|
987
|
+
if self._registry.versioning and len(execution_started_events) > 0:
|
|
988
|
+
version_failure = self.evaluate_orchestration_versioning(
|
|
989
|
+
self._registry.versioning,
|
|
990
|
+
ctx.version
|
|
991
|
+
)
|
|
992
|
+
if version_failure:
|
|
993
|
+
self._logger.warning(
|
|
994
|
+
f"Orchestration version did not meet worker versioning requirements. "
|
|
995
|
+
f"Error action = '{self._registry.versioning.failure_strategy}'. "
|
|
996
|
+
f"Version error = '{version_failure}'"
|
|
997
|
+
)
|
|
998
|
+
raise pe.VersionFailureException
|
|
999
|
+
|
|
903
1000
|
# Get new actions by executing newly received events into the orchestrator function
|
|
904
1001
|
if self._logger.level <= logging.DEBUG:
|
|
905
1002
|
summary = _get_new_event_summary(new_events)
|
|
@@ -910,6 +1007,15 @@ class _OrchestrationExecutor:
|
|
|
910
1007
|
for new_event in new_events:
|
|
911
1008
|
self.process_event(ctx, new_event)
|
|
912
1009
|
|
|
1010
|
+
except pe.VersionFailureException as ex:
|
|
1011
|
+
if self._registry.versioning and self._registry.versioning.failure_strategy == VersionFailureStrategy.FAIL:
|
|
1012
|
+
if version_failure:
|
|
1013
|
+
ctx.set_failed(version_failure)
|
|
1014
|
+
else:
|
|
1015
|
+
ctx.set_failed(ex)
|
|
1016
|
+
elif self._registry.versioning and self._registry.versioning.failure_strategy == VersionFailureStrategy.REJECT:
|
|
1017
|
+
raise pe.AbandonOrchestrationError
|
|
1018
|
+
|
|
913
1019
|
except Exception as ex:
|
|
914
1020
|
# Unhandled exceptions fail the orchestration
|
|
915
1021
|
ctx.set_failed(ex)
|
|
@@ -959,6 +1065,9 @@ class _OrchestrationExecutor:
|
|
|
959
1065
|
f"A '{event.executionStarted.name}' orchestrator was not registered."
|
|
960
1066
|
)
|
|
961
1067
|
|
|
1068
|
+
if event.executionStarted.version:
|
|
1069
|
+
ctx._version = event.executionStarted.version.value
|
|
1070
|
+
|
|
962
1071
|
# deserialize the input, if any
|
|
963
1072
|
input = None
|
|
964
1073
|
if (
|
|
@@ -1221,6 +1330,48 @@ class _OrchestrationExecutor:
|
|
|
1221
1330
|
# The orchestrator generator function completed
|
|
1222
1331
|
ctx.set_complete(generatorStopped.value, pb.ORCHESTRATION_STATUS_COMPLETED)
|
|
1223
1332
|
|
|
1333
|
+
def evaluate_orchestration_versioning(self, versioning: Optional[VersioningOptions], orchestration_version: Optional[str]) -> Optional[pb.TaskFailureDetails]:
|
|
1334
|
+
if versioning is None:
|
|
1335
|
+
return None
|
|
1336
|
+
version_comparison = self.compare_versions(orchestration_version, versioning.version)
|
|
1337
|
+
if versioning.match_strategy == VersionMatchStrategy.NONE:
|
|
1338
|
+
return None
|
|
1339
|
+
elif versioning.match_strategy == VersionMatchStrategy.STRICT:
|
|
1340
|
+
if version_comparison != 0:
|
|
1341
|
+
return pb.TaskFailureDetails(
|
|
1342
|
+
errorType="VersionMismatch",
|
|
1343
|
+
errorMessage=f"The orchestration version '{orchestration_version}' does not match the worker version '{versioning.version}'.",
|
|
1344
|
+
isNonRetriable=True,
|
|
1345
|
+
)
|
|
1346
|
+
elif versioning.match_strategy == VersionMatchStrategy.CURRENT_OR_OLDER:
|
|
1347
|
+
if version_comparison > 0:
|
|
1348
|
+
return pb.TaskFailureDetails(
|
|
1349
|
+
errorType="VersionMismatch",
|
|
1350
|
+
errorMessage=f"The orchestration version '{orchestration_version}' is greater than the worker version '{versioning.version}'.",
|
|
1351
|
+
isNonRetriable=True,
|
|
1352
|
+
)
|
|
1353
|
+
else:
|
|
1354
|
+
# If there is a type of versioning we don't understand, it is better to treat it as a versioning failure.
|
|
1355
|
+
return pb.TaskFailureDetails(
|
|
1356
|
+
errorType="VersionMismatch",
|
|
1357
|
+
errorMessage=f"The version match strategy '{versioning.match_strategy}' is unknown.",
|
|
1358
|
+
isNonRetriable=True,
|
|
1359
|
+
)
|
|
1360
|
+
|
|
1361
|
+
def compare_versions(self, source_version: Optional[str], default_version: Optional[str]) -> int:
|
|
1362
|
+
if not source_version and not default_version:
|
|
1363
|
+
return 0
|
|
1364
|
+
if not source_version:
|
|
1365
|
+
return -1
|
|
1366
|
+
if not default_version:
|
|
1367
|
+
return 1
|
|
1368
|
+
try:
|
|
1369
|
+
source_version_parsed = parse(source_version)
|
|
1370
|
+
default_version_parsed = parse(default_version)
|
|
1371
|
+
return (source_version_parsed > default_version_parsed) - (source_version_parsed < default_version_parsed)
|
|
1372
|
+
except InvalidVersion:
|
|
1373
|
+
return (source_version > default_version) - (source_version < default_version)
|
|
1374
|
+
|
|
1224
1375
|
|
|
1225
1376
|
class _ActivityExecutor:
|
|
1226
1377
|
def __init__(self, registry: _Registry, logger: logging.Logger):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: durabletask
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A Durable Task Client SDK for Python
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -36,6 +36,7 @@ License-File: LICENSE
|
|
|
36
36
|
Requires-Dist: grpcio
|
|
37
37
|
Requires-Dist: protobuf
|
|
38
38
|
Requires-Dist: asyncio
|
|
39
|
+
Requires-Dist: packaging
|
|
39
40
|
Dynamic: license-file
|
|
40
41
|
|
|
41
42
|
# Durable Task SDK for Python
|
|
@@ -217,10 +218,11 @@ make test-unit
|
|
|
217
218
|
|
|
218
219
|
### Running E2E tests
|
|
219
220
|
|
|
220
|
-
The E2E (end-to-end) tests require a sidecar process to be running. You can use the Dapr sidecar for this or run a Durable Task test sidecar using the following
|
|
221
|
+
The E2E (end-to-end) tests require a sidecar process to be running. You can use the Dapr sidecar for this or run a Durable Task test sidecar using the following command:
|
|
221
222
|
|
|
222
223
|
```sh
|
|
223
|
-
|
|
224
|
+
go install github.com/microsoft/durabletask-go@main
|
|
225
|
+
durabletask-go --port 4001
|
|
224
226
|
```
|
|
225
227
|
|
|
226
228
|
To run the E2E tests, run the following command from the project root:
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
durabletask/__init__.py,sha256=1PTnFPvigLCs2apa7ITASeqqFOS09Zn-rrllyWeoDJE,263
|
|
2
|
+
durabletask/client.py,sha256=VrHXntWfSk4xYAv7JkOOXgNoFzefYWcD7UPGgn2zuWM,10312
|
|
3
|
+
durabletask/task.py,sha256=LCtKrDh_Yb94Zjxx8fUtXt3z5GwSaV-EieIFXKeZNOI,18404
|
|
4
|
+
durabletask/worker.py,sha256=fmKqjrBdU3eTq9sdVhFyjbMPgg_b60ASHggdsKvcaJQ,73669
|
|
5
|
+
durabletask/internal/exceptions.py,sha256=GVtYAhyCtoPFcbddW2rClskBIc1FkcqTOCz_EZiBd9o,176
|
|
6
|
+
durabletask/internal/grpc_interceptor.py,sha256=KGl8GGIbNdiEnWVLwQwkOemWvIlcEO0dh-_Tg20h5XA,2834
|
|
7
|
+
durabletask/internal/helpers.py,sha256=7A1Bb-KNuAovQTOh9mxeTFahCPtl45C5j5tUJ43BXuo,7538
|
|
8
|
+
durabletask/internal/orchestrator_service_pb2.py,sha256=q4elBQnofrZ4eYVCVnmed4vsa-FLNFLeBRtFOZYhTv8,44631
|
|
9
|
+
durabletask/internal/orchestrator_service_pb2.pyi,sha256=FFxZhxdV7SX0pKxwKPHTGaAdXKowXnib4WvjhGFw2eo,66480
|
|
10
|
+
durabletask/internal/orchestrator_service_pb2_grpc.py,sha256=5xhDLJ73Ipsp1tjwWhUqVqEm30MjWHlj71zfPNBehWc,54366
|
|
11
|
+
durabletask/internal/shared.py,sha256=dKRGU8z1EQM4_YA6zkKeKfiaWbiZ6-B8lP-wHy7Q_jI,4379
|
|
12
|
+
durabletask-0.4.0.dist-info/licenses/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
|
|
13
|
+
durabletask-0.4.0.dist-info/METADATA,sha256=7ua3w7kWAdszCcUvchLxY_wWFdPd2r6Bb_Ca6N57_sk,12894
|
|
14
|
+
durabletask-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
+
durabletask-0.4.0.dist-info/top_level.txt,sha256=EBVyuKWnjOwq8bJI1Uvb9U3c4fzQxACWj9p83he6fik,12
|
|
16
|
+
durabletask-0.4.0.dist-info/RECORD,,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
durabletask/__init__.py,sha256=5YY3OLjqPt2tL8c9MLMn5eDfkMQgNIzYP7ir8MJtD-M,223
|
|
2
|
-
durabletask/client.py,sha256=vAm7BtVHeeWFVoiwvOGcrhrkand43oBCCVNnzbNfH6I,10011
|
|
3
|
-
durabletask/task.py,sha256=Brxt-cFqFaIjU07UFLCQoRv7ioycOLcJQbRh9Je_UW4,17722
|
|
4
|
-
durabletask/worker.py,sha256=D9TTl6QZ9f5uYvFNZnEAndgkqWRKkV66UNGLgp59sDY,66491
|
|
5
|
-
durabletask/internal/grpc_interceptor.py,sha256=KGl8GGIbNdiEnWVLwQwkOemWvIlcEO0dh-_Tg20h5XA,2834
|
|
6
|
-
durabletask/internal/helpers.py,sha256=G4nEhLnRUE1VbFHkOMX277_6LSsMH9lTh9sXUD0GdHM,7289
|
|
7
|
-
durabletask/internal/orchestrator_service_pb2.py,sha256=nkADgSglhimtNjAuISJdBz1bwA8xYm1cEQdL9ZifsmU,33993
|
|
8
|
-
durabletask/internal/orchestrator_service_pb2.pyi,sha256=99AIPzz4AdXrkQrN2MHkHkW9zKqmH4puSwvg9ze5IjA,50517
|
|
9
|
-
durabletask/internal/orchestrator_service_pb2_grpc.py,sha256=mZXK0QtvaRr6cjm8gi9y-DjMNR2Xg2Adu79WsR22pQc,41146
|
|
10
|
-
durabletask/internal/shared.py,sha256=dKRGU8z1EQM4_YA6zkKeKfiaWbiZ6-B8lP-wHy7Q_jI,4379
|
|
11
|
-
durabletask-0.3.0.dist-info/licenses/LICENSE,sha256=ws_MuBL-SCEBqPBFl9_FqZkaaydIJmxHrJG2parhU4M,1141
|
|
12
|
-
durabletask-0.3.0.dist-info/METADATA,sha256=yy_ChhOJe2RiOkp_QvGzLEUvMaluwBmVd8H0Rfi58kg,12958
|
|
13
|
-
durabletask-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
14
|
-
durabletask-0.3.0.dist-info/top_level.txt,sha256=EBVyuKWnjOwq8bJI1Uvb9U3c4fzQxACWj9p83he6fik,12
|
|
15
|
-
durabletask-0.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|