Skip to content
30 changes: 22 additions & 8 deletions examples/workflow/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import uuid
from datetime import timedelta
from time import sleep
from time import monotonic, sleep

from dapr.clients.exceptions import DaprInternalError
from dapr.conf import Settings
Expand All @@ -30,14 +31,16 @@
child_orchestrator_count = 0
child_orchestrator_string = ''
child_act_retry_count = 0
instance_id = 'exampleInstanceID'
child_instance_id = 'childInstanceID'
instance_id = f'exampleInstanceID-{uuid.uuid4()}'
workflow_name = 'hello_world_wf'
child_workflow_name = 'child_wf'
input_data = 'Hi Counter!'
event_name = 'event1'
event_data = 'eventData'
non_existent_id_error = 'no such instance exists'
first_phase_timeout_seconds = 20
poll_interval_seconds = 0.5
expected_child_orchestrator_string = '1aa2bb3cc'

retry_policy = RetryPolicy(
first_retry_interval=timedelta(seconds=1),
Expand Down Expand Up @@ -116,6 +119,15 @@ def act_for_child_wf(ctx: WorkflowActivityContext, inp):
child_act_retry_count += 1


def wait_for_first_phase():
"""Block until the activities and the child workflow before the event wait have finished."""
deadline = monotonic() + first_phase_timeout_seconds
while child_orchestrator_string != expected_child_orchestrator_string or retry_count < 2:
if monotonic() > deadline:
raise TimeoutError('Workflow did not finish its initial activities in time')
sleep(poll_interval_seconds)


def main():
wfr.start()
wf_client = DaprWorkflowClient()
Expand All @@ -127,12 +139,14 @@ def main():

wf_client.wait_for_workflow_start(instance_id)

# Sleep to let the workflow run initial activities
sleep(12)
# Poll until the initial activities are done instead of sleeping for a fixed time.
wait_for_first_phase()

assert counter == 11
# The counter is the sum of the two hello_act inputs (1 and 10), and the retryable
# activity fails once then succeeds, so it runs exactly twice.
assert counter == 1 + 10
assert retry_count == 2
assert child_orchestrator_string == '1aa2bb3cc'
assert child_orchestrator_string == expected_child_orchestrator_string

# Pause Test
wf_client.pause_workflow(instance_id=instance_id)
Expand All @@ -144,7 +158,7 @@ def main():
metadata = wf_client.get_workflow_state(instance_id=instance_id)
print(f'Get response from {workflow_name} after resume call: {metadata.runtime_status.name}')

sleep(2) # Give the workflow time to reach the event wait state
# External events raised before the workflow waits for them are buffered.
wf_client.raise_workflow_event(instance_id=instance_id, event_name=event_name, data=event_data)

print('========= Waiting for Workflow completion', flush=True)
Expand Down
Loading