Symfony-docs: Workflow, document (best?) practices

Created on 28 May 2018  Â·  17Comments  Â·  Source: symfony/symfony-docs

_I've crawled over the ~4 pages of documentation on workflow from the symfony site which have been enough to get me to this point._

Unfortunately, the documentation I link to above focuses strictly on bootstrapping the component. There isn't as much as I'd like to see about any of the ways it its outputs can be used. I'm opening this ticket because while functionally I'm getting the output I desire, I'm in the phase now where I like to reflect on my usage of a new component and inquire about best practices.

I think my most specific thoughts/questions/facts are:

  • I am using the MultipleStateMarkingStore implementation
  • When the marking store calls my getState method, I'm currently assembling the state array based on various bits of information I infer from my domain graph.

    • Therefore, I do not serialize and store the entire state array because some _states/places_ originate from outside my _subject_ (related models).

    • Currently, my state transitions always transition from a collection of places, to a single place. This is because I only care about the one value and will regenerate the others from my domain in getState during future checks:

      new Transition(AddonSubscriptionTransition::INSTALL_FREE, [AddonSubscriptionState::INACTIVE, AddonSubscriptionState::FREE, AddonSubscriptionState::TRIAL_UNAVAILABLE], [AddonSubscriptionState::ACTIVE]),

      This kind of implies that I will only use a _subject_ once per load.

    • When the marking store calls setState on my model, I'm only going to interpret the value to determine what data I need to write to the database.

  • So far, I've avoided using events because I feel comfortable interpreting the resultant setState call. But should I not be doing that and specifically focusing on using the events API of workflow to act on my data?

So, generally speaking, I'm looking for some anti-pattern advice, but I think some of this might do well to be codified somehow in the documentation so that people aren't inadvertently subverting the intended design of this very useful component!

_I might update this description if I dream up better ways of explaining things, I hope you get the gist of what I'm after._ 😄

Waiting feedback Workflow

All 17 comments

@atrauzzi thanks for helping us improve Symfony Docs. I can't help you here, but I'm pinging our main Workflow experts for their comments: @lyrixx and @HeahDude. Thanks!

Hello @atrauzzi, if you need a full control when writing and reading a state in your model, you should then use a custom MarkingStoreInterface implementation, to keep this logic outside of your model and bridge it in the Workflow component.

You would then need to replace the configuration by the following:

framework:
    workflows:
        some_entity_name:
            type: 'workflow'
            marking_store:
                service: App\Workflow\SomeEntityMarkingStore

@HeahDude - I don't mind using the current marking store and reading the array it provides, is there any reason I would want to use my own beyond that?

(Also, just to note: I'm not using this as part of a symfony project, so the YAML configs aren't really an option for me.)

I don't mind using the current marking store and reading the array it provides, is there any reason I would want to use my own beyond that?

Yes, this separates concerns, so it follows best practices.
Your entity setter should stay simple, not handle the resulting logic of the Workflow component.
A custom MarkingStore could call many setters for example or one among others, and allows you to do whatever you want on your model instead of letting the property accessor call setMarking().

Hi.

About this transition:

new Transition(AddonSubscriptionTransition::INSTALL_FREE,
    [AddonSubscriptionState::INACTIVE, AddonSubscriptionState::FREE, AddonSubscriptionState::TRIAL_UNAVAILABLE],
    [AddonSubscriptionState::ACTIVE]),

Do you know you object should be in all three places (AddonSubscriptionState::INACTIVE, AddonSubscriptionState::FREE, AddonSubscriptionState::TRIAL_UNAVAILABLE) in order to pass through the transition ? If you are OK with that, it's perfect.


About the Custom Marking Store: Indeed it will be cleaner to use it. But you don't have to. But still ;)


Side node: You should never alter the state of your object directly.
If you call $workflow->can('A'), then if you do something will your model, another call to $workflow->can('A') should returns the same results. Always.

So be careful when you modify some information in your entity.


Finally, I don't have access to your code, but it looks like there is something strange here. Usually, you should not care about call to setState. the workflow manage it's own state. So it looks like you are using it but in a special/wrong way.

@lyrixx

  • Transition: Yes! That's totally what I expect and that the resultant state in the component will be ACTIVE.
  • To me, making a custom marking store isn't necessary. But more on that in a moment.
  • In my list of states, the only one that isn't altered directly is ACTIVE/INACTIVE. The remaining ones are generated from the current state of related models.

So that leaves the _"strange"_ part. Unfortunately, the state I'm wanting to check on isn't summarized in any way. I'm feeding data into the state machine that comes from getState, but is effectively "read only" as far as the state machine is concerned.
All I'm really asking it for is _"can I transition to ACTIVE/INACTIVE -- when these other things you don't control are true"_.

Hi @atrauzzi

Is this issue still pending?

I'd say so, yeah. I think only half the story is presented in the current documentation. Effective, practical usage of workflow is not quite evident and all we're really shown currently are the core types.

Can you name some „headlines“ you would want to read? This could maybe help us to get into the right direction and split this issue in smaller pull requests

@atrauzzi do you mean you need/want more « real userland » code using workflow component inside the documentation?

Or you want to use it in a special way and you miss some docs? Also you can read the code doc classes or interfaces sometimes it helps

More userland 🙂

it is maybe more some blog posts (symfony or other dev teams) then, to see more use cases of this component
also maybe you can ask for a feature being implemented in the symfony/demo repo :)

i think not it should be inside the doc

Hmm, I think the docs are still the right place. The first spot I looked for examples are here.

I really think there needs to be something to help people get started. Some kind of guidance. It's way too vague to just be given this base class and no idea of its lifecycle as it relates to one's own application.

I'm not asking for solutions on specific domain, but the nature by which specific domain code interacts with this component.

_I've crawled over the ~4 pages of documentation on workflow from the symfony site which have been enough to get me to this point._

At first, and much to my frustration, I thought the documentation for Workflow was extremely inadequate.
But then I found that there are two documentation sections for Workflow:

The latter is much more detailed.
It took me a while to find the second one, since the first page was the first result in Google and I didn't expect there to be another doc section.

I really think they should be merged or, at least, have prominent links to one another.

:+1: I already reported that to the doc team. It's really hard to find all pages.

Would you mind creating a PR @milosa ?

I'm closing this old issue because we've made many changes in the Workflow component docs since the issue was opened. Thanks.

But did they address anything?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

javiereguiluz picture javiereguiluz  Â·  3Comments

Nyholm picture Nyholm  Â·  4Comments

lbayerl picture lbayerl  Â·  3Comments

javiereguiluz picture javiereguiluz  Â·  3Comments

wouterj picture wouterj  Â·  4Comments