Skip to content

[Workflow] Choose which Workflow events should be dispatched #36617

Closed
@stewartmalik

Description

@stewartmalik

Description
Provide a way to choose which events are to be dispatched by the Workflow component.

Background
Currently I have an application that processes orders. See below for Workflow places and transitions:

            places:
                - new
                - sent
                - saved_order_id
                - in_progress
                - order_complete
                - activated
                - complete
                - failed
            transitions:
                send:
                    from: new
                    to:   sent
                save_order_id:
                    from: sent
                    to: saved_order_id
                check:
                    from: saved_order_id
                    to: in_progress
                complete_order:
                    from: in_progress
                    to: order_complete
                activate:
                    from: order_complete
                    to: activated
                complete:
                    from: activated
                    to:   complete
                fail:
                    from: [ 'new', 'sent', 'saved_order_id', 'in_progress', 'order_complete', 'activated' ]
                    to: failed

I have workflows that assist in maintaining the state of the order. Currently my code listens for Guard Events and performs some action based on the state of the workflow.

For example when attempting to place an order via a third party API I have implemented a Guard Event Listener for the send transition. In the EventListener I attempt to call the third party API to place the order, if this fails I return a TransitionBlocker which prevents the transition from taking place. This all works perfectly.

My current issue is that when a transition has taken place successfully, the Workflow component calls the announce() method so that we can find which new transitions are now possible for the new place. The issue with this is that the announce() method eventually calls buildTransitionBlockerListForTransition() but with possible transitions for the new place the order is in. In the above example if the send transition completes successfully buildTransitionBlockerListForTransition() is called with save_order_id as the transition.

This then dispatches the Guard Event for the save_order_id transition even though we’ve only explicitly called Workflow->apply() on the send transition. The effect of this is that Guard Event Listeners for the save_order_id transition fire prematurely.

While this isn’t an issue for some transitions of the Workflow, for Guard Event Listeners that contact a third party API, or perform some kind of state change with the order, it means this state change happens before we explicitly call the transition where it should occur. Then when we actually call the next transition ourselves sometime later it happens for a second time.

Proposal
Provide some method of choosing which events the Workflow component should dispatch for a specific workflow.

In an ideal scenario I think this could be added as an optional configuration item for each workflow definition. An array that contains all events that should be dispatched, or the inverse, an array that defines which events should be excluded from being dispatched.

For example:

framework:
    workflows:
        some_workflow:
            type: state_machine
            events: ['leave', 'enter', 'entered', 'completed']
            audit_trail:
                enabled: true
...

Thank you for taking the time to read this proposal :)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions