question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[workflow] Sending signal to specific workflow/step

See original GitHub issue

With workflow events, we are able to read data from external sources, i.e., sleep or some external queue.

Sometimes users want to send a specific event to a specific workflow/step. One way to do this is to have an event dispatcher which will dispatch the event to the specific step. But the downside is that it’s not scalable and also if there is some garbage to the queue, it doesn’t know when to delete them.

What we need here is a event provider for workflow and this event provide can send event from outside.

class WorkflowEventProvider(EventListener):
    # These two are API from EventListener
    async def poll_for_event(self, event_type) -> Event:
        ...
    async def event_checkpointed(self, event: Event):
        ...

   # This is the API to send event
   async def signal(self, workflow_id: Optional[str], event: Event):
       ...

With this, to implement a contract approval workflow, we’ll do:

# s1 will create a contract and send the contract to the person for an approval
s1 = generate_contract.step(contract_object, need_approval="tom@gmail.com")

def approve_event(contract):
    e = workflow.wait_for_event(WorkflowEventProvider, contract.id)

    @workflow.step
    def next_step(approval_result):
        if approval_result == "APPROVE":
              return finalize_contract.step(contract)
       else:
            return reject_contract.step(contract)
    return next_step.step(e)

approve_event.step(s1).run_async(workflow_id="contract")

Then the workflow will block in waiting to approval.

To approve the contract, we’ll need:

event_provider = WorkflowEventProvider()
event_provider.signal("contract", "APPROVE")

Then the “contract” workflow should resume.

Some implementations ideas:

  • short term [ok for now]
    • Right now, we run poll_for_event in a event loop. So for this specific function, it can sleep and poll from a detached actor. signal will tell the detached actor that the event is ready. Here, the detached actor need to record the event for fault tolerance.
  • long term [need update workflow.wait_for_event]
  • The long term version of workflow.wait_for_event will be implemented without the event loop. It’ll
    1. register the waiting info in a detached actor
    2. before the waiting finished, it’ll suspend the workflow to release the resource
    3. when event is finished, it’ll write the results to the wait_for_event step and just resume the workflow.
  • with this the implementation will be much easier, basically, signal will just tell the coordinator it’s ready and resume the suspended ones.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:21 (17 by maintainers)

github_iconTop GitHub Comments

2reactions
iychengcommented, Feb 1, 2022

@yuanchi2807 it’s not correct. .step() returns object, so you can’t use this: if is_event_approved.step(w):

Keep in mind that event/steps are both Workflow and you can’t dereference it unless you pass it to inputs.

def eventnode(forms, approver, subscribed_event):
    input_form, output_form = forms
    notify_approver(input_form, approver)
    w = workflow.wait_for_event(WorkflowEventProvider, subscribed_event)
    @workflow.step
    def is_event_approved(wf_event):
        if wf_event.get('approved'):
            output_form['approver'] = 'approved'
            return (input_form, output_form)
        else:
            return contract_wf.step((input_form, {}))
    

@iycheng Follow up question on a step function inside another step function, such as is_event_approved() above. When the outer step eventnode() failed after w is received, does reexecution of eventnode() recover w?

The event is designed to be fault tolerance, so this is OK. Btw, you need to try to understand it as nested workflow.

Maybe due to the bad documentation, but I feel you are not understanding how workflow dag is organized. Some notes here:

  • .step() or .wait_for_event returns a Workflow object
  • Workflow object can’t be dereferenced and you can only dereference it by .run or passing it to another workflow step
  • If you return a workflow inside a workflow step, the inner one is becoming nested workflow. It’ll be executed after the outer function is finished.
2reactions
iychengcommented, Jan 21, 2022

An event may be thought as a special type of input data to a step and thus its arrival is checkpointed?

Yes. workflow.wait_for_event returns a Workflow object. All the FT-related things are the same as normal workflow objects.

Here, when should the event step finish depends on what do we do in the event provider.

  • it can ask for a specific event_type to come
  • multiple steps can subscribe to the same event_type
  • it should have data that comes with the event.

@yuanchi2807

Read more comments on GitHub >

github_iconTop Results From Across the Web

Add steps to a workflow | Slack
There are three types of steps you can add to workflows: messages, forms, and steps from apps installed to your workspace. Message steps....
Read more >
Workflow actions in SharePoint Designer: A quick reference ...
Use this action to record what a workflow has performed at a particular instance in its lifecycle. For example, you can log a...
Read more >
send-workflow-step-state - AWS Documentation
Used to distinguish between multiple callbacks for multiple Lambda steps within the same execution. --status (string). Indicates whether the specified step ...
Read more >
Send A Signal To A Workflow - Docs - Infinitic
It is possible to send a signal to running workflows. Sending signals is done through channels that must be described in the workflow...
Read more >
Configuring Object Workflows - Vault Help
Optional: Create message templates for any notifications or task reminders ... A Task workflow step assigns a task to users in a specific...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found