Make a process singleton

I have this case where the process must be fired when a specific CDT is created but only once.

Is there an easy way to make sure of that?

I though of setting up through the start node some kind of expression to be fired when a certain query returns a count higher than 0 or anything alike. That doesn't seem possible and the other problem is it seems I can't enforce the creation of the process only once at all. Lets say in my case two CDT are created at "the same time" I'll end up for sure with two process threads?

Or perhaps I'm approaching my problem the wrong way.

If you have any ideas please share, thanks!

  Discussion posts and replies are publicly visible

  • Worst case we can adapt the solution so that the process responsible of creating the CDT triggers the other process.

    But what "gateway" might I provide to make sure the process is started only once? Let's say this other process (sub process node) creates a task at first, I could always check if the task already exists and if it does don't start it.

    But what will happen if 2 users at the same time does the same operation I wonder? I think there's still a risk of having more than one instance.
  • 0
    Certified Lead Developer
    Can you tell us a little bit more about your use case need to have only one process instance? And do you mean a CDT is created or a new row of data associated to that CDT? Because off the top of my head I'm not sure how to have a process monitor for creation of a particular CDT if the CDT in question doesn't exist yet - that's a big contradiction.
  • 0
    Certified Lead Developer
    Maybe look at the @version annotation if you're using a database? I think this would only be helpful if you know what the PK is going to be, and are updating an existing row.
  • Yeah with context it might help, I'll give a quick example :

    Let's say the client wants to manage inventory. So through an existing action/form or some sort we can create inventory (your CDT). At one point the client wants to manage all the inventory rapidly under one task and one interface only. So when a CDT is created automatically we create this task that links to a dashboard of all inventory. No inventory? No task/dashboard needed. One or more inventory? One dashboard accessible through the one task link. They don't want one task per inventory item.

    So we thought about using numprocessesforprocessmodelforstatus() function as a gateway when the inventory is created to lunch a new process that creates the task / dashboard interface but afraid of duplicates of the process as we truly just want one max.
  • Well we tried with a numprocessesforprocessmodelforstatus and if your fast enough it will create 2 same process sadly, we used the following gateway `

    IF (=numprocessesforprocessmodelforstatus(0000, "active", false) > 0) THEN GOTO END NODE
    ELSE CREATE PROCESS XYZ with dashboard/task

    I think the way to go is through SQL perhaps and keep a flag within a table of some sort? Through an insert the first thread would lock? running out of ideas.
  • 0
    Certified Associate Developer
    in reply to karlg
    If I understand your use case correctly, I think you'd want to use records and you would want to use either entity backed or expression backed records. Using your example, you could create a record of type "inventory" that referenced the CDT/data store entity of type Inventory. You could then take actions on these inventory items by using related actions. Creating a new inventory item would probably come from an action that would use the Write to Datastore" service to add a new item to the inventory record list. To mitigate your duplication concern, I'd recommend flagging to the user that there is a similar inventory item already created and allowing them to remove or merge the new added inventory item with the existing one. Does this make sense?
  • It does nathan.schmitz and thank you for your response and time.

    The only thing I needed to specify in my case is that inventory can be asked from anyone at any time for example. The second an inventory is created through an action like you mentioned we need to start the process. But that is true for any inventory from anyone at any time. So let's say 2 users asks for anything (even the same thing) from inventory, at the same time, I still need to handle this case and start off only once a specific process.

    As mentionned if your fast enough (within the same second) it will trigger more than one process instance even though I've provided a gateway mentionning if more than one instance of active process of XYZ do nothing.
  • 0
    Certified Associate Developer
    in reply to karlg
    In the solution I'm proposing we are locking the data, not the process. When designing the inventory CDT, we include a version attribute that uses the @Version annotation. This will ensure that the data that we are writing back to the database is the same as the version when we started the process thus ensuring data integrity. Does this make sense?
  • Oh my bad, let's say we include a version annotation wouldn't it be the same problem as the flag would be within the database instead? Let's go with :

    Process ABC that creates the inventory in the database.

    Process XYZ that must be a singleton, created when no other XYZ is present and when we have at least one inventory that was created.

    Within ABC, after creating/writing in the database the inventory cdt, we put a gateway based of the attribute version of the CDT that indicates if we fire the process XYZ or not?

    We tried with a flag within the database (a simple table with a boolean) which would be the same technically and it created two XYZ process instances. Unless my understanding is wrong of what you are proposing.
  • +1
    Certified Lead Developer
    in reply to karlg
    Why is it a requirement to only have one process instance? Why not just launch the process, check for the lock in the database, continue with the process if there is no lock, but terminate the process instance if there is a lock?