Variable OMS execution time

mihaistana
mihaistana Backend dev Posts: 3 🧑🏻‍🚀 - Cadet

I need to check the status of payments with the OMS as follows

every minute for the first 6 hours (this is the default)
every 15 minutes from 6 hours to 48 hours.

How can I do this with the OMS?

I tried to modify the getStateMachineLockerTimeoutInterval() from the OmsConfig but if I change it to 15 minutes it's applied to all the orders from the first check

Tagged:

Comments

  • fsmeier
    fsmeier Senior Software Engineer & Developer Enablement Advocate Sprykee Posts: 1,082 ⚖️ - Guardians (admin)

    Heyhey @mihaistana ,

    I would not change the getStateMachineLockerTimeoutInterval() for this purpose since you would affect all other OMS parts as well.

    I would work with a timeoutProcessor within you do the logic of

    every minute for the first 6 hours (this is the default)
    every 15 minutes from 6 hours to 48 hours.

    For example something like this:

    Code:

    <?xml version="1.0"?>
    <statemachine
        xmlns="spryker:oms-01"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="spryker:oms-01 http://static.spryker.com/oms-01.xsd">
    
        <process name="Showcase01" main="true">
    
            <states>
                <state name="new" />
                <state name="payment pending" />
                <state name="invalid" />
                <state name="cancelled" />
                <state name="paid" />
            </states>
    
            <transitions>
                <transition happy="true" condition="DummyPayment/IsAuthorized">
                    <source>new</source>
                    <target>payment pending</target>
                    <event>authorize</event>
                </transition>
    
                <transition>
                    <source>new</source>
                    <target>invalid</target>
                    <event>authorize</event>
                </transition>
    
                <transition>
                    <source>new</source>
                    <target>cancelled</target>
                    <event>cancel</event>
                </transition>
    
                <transition happy="true" condition="DummyPayment/IsPayed">
                    <source>payment pending</source>
                    <target>paid</target>
                    <event>pay</event>
                </transition>
    
                <transition happy="true" condition="DummyPayment/ShouldTryAgain">
                    <source>payment pending</source>
                    <target>payment pending</target>
                    <event>pay</event>
                </transition>
    
                <transition>
                    <source>payment pending</source>
                    <target>cancelled</target>
                    <event>cancel</event>
                </transition>
    
            </transitions>
    
            <events>
                <event name="authorize" timeout="1 second" />
                <event name="pay" manual="true" timeout="1 minute" timeoutProcessor="OmsTimeout/Initiation"/>
                <event name="cancel" manual="true"/>
            </events>
        </process>
    
    </statemachine>
    
    

    Dont do extra database queries in the timeoutProcessor unless you really need to. Remember, the events and states etc are done on item-level, not on order level.

    Hope this guides you into the right direction.

    All the best,

    Florian

  • mihaistana
    mihaistana Backend dev Posts: 3 🧑🏻‍🚀 - Cadet

    Hi @fsmeier

    Thank you!
    I was thinking to do something like that but it's not clear in the documentation if the timeoutProcessor executes the task after the timeout (6 hours) only once and if it's executed every minute until it return true.

    if it's executed every minute my first thought it's to add a redis key where it's saved the last execution and if it's less than 15 minutes ago ignore it.

  • fsmeier
    fsmeier Senior Software Engineer & Developer Enablement Advocate Sprykee Posts: 1,082 ⚖️ - Guardians (admin)

    Heyhey @mihaistana ,

    so the timeoutProcessor is for checking if the timeout based on your logic is hit or not. So in there you would specify if the timeout should be 1 minute or 15 minutes. Based on the order-item-creation time. this information you get passed within the timeoutProcessor. No need for redis at all here. you already have all information.

    The timeoutProcessor is executed whenever an item gets into a certain state. So when you look in my POC i posted whenever you reach "payment pending" state the timeoutProcessor will be executed again. and based on it the timestamp is written in the DB which determines the exact timeout (1min or 15min) - based on the background tasks it will likely not be exactly 1min or 15min but with a small delay depending on the jenkins task.

    All the best,

    Florian

  • mihaistana
    mihaistana Backend dev Posts: 3 🧑🏻‍🚀 - Cadet

    Thank you @fsmeier

    I think it's more clear now :)

    Regards

    Mihai