Calling Developers!
We are reenergizing our code contribution process! Learn More

What are the Slack Archives?

It’s a history of our time together in the Slack Community! There’s a ton of knowledge in here, so feel free to search through the archives for a possible answer to your question.

Because this space is not active, you won’t be able to create a new post or comment here. If you have a question or want to start a discussion about something, head over to our categories and pick one to post in! You can always refer back to a post from Slack Archives if needed; just copy the link to use it as a reference..

I've struggled for quite a while to understand something quite fundamental about the OMS. Even thoug

Options
U01SE4SRCU9
U01SE4SRCU9 Posts: 68 🧑🏻‍🚀 - Cadet
edited September 2021 in Knowledge Sharing

I've struggled for quite a while to understand something quite fundamental about the OMS. Even though this is described in the related docs - https://documentation.spryker.com/docs/state-machine-cookbook -, for some reason it still wasn't immediately obvious for me and also took some code digging into the OMS until I could finally piece the picture together. So I wrote what I learned up in my own words, primarily for myself, in case I would forget again later on, but since I already have it in written form, I thought I share it here too, in case someone else would need it too:

"To disperse the mystery, this is the sequence:

  1. The OMS checks all possible transitions THAT DO NOT HAVE ANY EVENTS for the current state
  2. If a transition can be made (as the condition is fulfilled or there is no condition at all), it does the transition (so the orderItem is now in the next state, its source and target is now different)
  3. THEN it checks if the TARGET state (NOT the SOURCE) has an onEnter event.
  4. If it has - and if source and state for the orderItem are different, meaning, a transition has indeed happened -, it fires the event.
    Thus, the transition is completed.

• So, in effect, the event IS indeed fired "first" when we're looking at how a state is entered and what follows from there, but the actual implementation in code is just the inverse, in the sense that in any given OMS transition evaluation run, the onEnter event is actually fired last - although indeed immediately upon entering the new state.
• And it is only from that point on, when the OMS considers the next possible transitions from this new state (starting again from 1. in the list above), that the "firstness" of the event firing is realized - since it has already happened at the end of the previous run and the OMS is only now (that the event was already triggered) evaluating the following possible transitions, incl. any conditions they may have.
• So the implementation is inverted (event comes last, at the end of the code that handles the transition from the current state), but looking at the big picture, the sequence of transitions, it happens "first" indeed, immediately upon entering the new state - just in the previous OMS transition run, not in the current one.
• From which also follows that for any order items that are ALREADY in a state to which you would add an onEnter event (one that it hasn't had before, when order items were first transitioned into it), the onEnter event you've just added will NEVER be triggered automatically (only for those that get transitioned into it AFTER your addition), because they are ALREADY IN IT. And, as stated above, events are NOT fired at the START of a given OMS transition evaluation run, but at the END, and NOT for the CURRENT state but for NEXT one (if any conditions for the transition to that have been fulfilled or there were no conditions at all and thus the transition has been made) - and even then ONLY if source and state are DIFFERENT."
• So if you want to add a new onEnter event that should also be triggered for orderItems that are ALREADY in a given state then don't add your new event to that state but instead create a new, intermediary one between the current state and the desired new one and put your event there - and keep any conditions for determining whether or not the transition to this intermediary state can be made, in the previous one (in which you already have some orderItems, for which you would like to have your new event triggered too).

Comments

  • profuel
    profuel SSA Sprykee Posts: 37 ✨ - Novice
    Options

    It doesn't sound quite right to me.
    Could you please make a drawing/screenshot of the process you struggled with and number the order of the execution.

  • U01SE4SRCU9
    U01SE4SRCU9 Posts: 68 🧑🏻‍🚀 - Cadet
    Options

    @UNU1XNMT9 It wasn't one specific process but the way the OMS works in general.
    • At first I didn't know - and so had to find out - that when the OMS first checks the next possible transitions for a given state, it doesn't even consider those that have an event at all.
    • I also didn't know that although the docs say that "events come first", in actual implementation they come last (check \Spryker\Zed\Oms\Business\OrderStateMachine\OrderStateMachine::checkConditionsForProcess and you'll see what I mean) and even then only if source and target are different.
    • Neither did I know that because of this, any event added to a pre-existing state will not be triggered anymore for any orders that are already in that state, because they are already there and so are not entering it anymore.
    So these are things that became clear to me only recently, after a good amount of docs and code reading.

  • profuel
    profuel SSA Sprykee Posts: 37 ✨ - Novice
    Options

    well, this is still not completely true.
    We do execute event (if any) and only then check condition (if any) of the transition.

  • U01SE4SRCU9
    U01SE4SRCU9 Posts: 68 🧑🏻‍🚀 - Cadet
    Options

    Ah, I believe I see what you mean now.
    So, are you saying that number 3. in my listing above is wrong and correctly it should be something like:

    1. Then it makes a separate check for possible transitions (from where the orderItem is now, so if a transition was already made in 2., then from there, if not, then from its original state) WITH onEnter events.

    ?

  • profuel
    profuel SSA Sprykee Posts: 37 ✨ - Novice
    edited September 2021
    Options

    yes, when OMS lands onto some status, we collect all transitions from it with
    • no events
    • enEnter events

  • profuel
    profuel SSA Sprykee Posts: 37 ✨ - Novice
    Options

    the thing is - we will run ONLY the first one matching for each item. which means you have to be careful here.

  • U01SE4SRCU9
    U01SE4SRCU9 Posts: 68 🧑🏻‍🚀 - Cadet
    Options

    Ok, thanks for the correction. 👍