Long running workflow with conditional transition - persistence

I have long-running workflow service, based on state machine, that at some point has to compare two values and if they are equal it should transition to a new state.
However, once I introduce trigerless transition with compare, workflow instance never goes to idle.
What is the best approach to do this, to have conditional transition that is evaluated once per entering source state, and goes back idle if condition is false.

Related

Temporary adjustment of delay time

I have the following problem which I am unable to solve:
I have a situation where a security point (added as delay) holds every half an hour a 15 min break. After the break, the security guards increase their speed till the queue is shorter than 10pp.
I wanted to model this as follows: a state chart with delay.set_capacity(0) after 30 minutes and delay.set_capacity(1) again after the 15 min break. For the increased speed after the break, I added an additional state with condition: queue.size()>10 and now I want to set the action such that the delay function changes the delay time from exponential (1/10) to exponential (1/5) as long as queue.size()>10.
Anyone experience with which function in the action box to use? Or would you suggest a different function?
Since you are using, or at least want to use a statechart I would suggest the following design, where you have composite states inside the working state to indicate if the security agent is working fast or normal and a message transition to let it move from one state to the next.
It is advised to use a message transition and trigger it as needed instead of a conditional state which gets chected for every change inside the agent since this can be a computational expensive exercise.
I assume you already implemented the correct capacity settings for the different on enter actions for working and breaking
Now you simply need to send the message every time an agent enters the queue and every time it exits the delay block, and of course, see the delay time based on the state of the statechart.
Aee screenshot below.

Delay Celery task based on condition

Is there any way to delay a Celery task from running based on a condition? Before it moves from scheduled to active I would like to perform a quick check to see if my machine can run the task based on the arguments provided and my machine's state at the time. If it's not, it halts the scheduled queue and waits until the condition is satisfied.
I've looked around at the following points but it didn't seem to cut it:
Celery's Signals: closest thing I could get to is task_prerun() but regardless of what I put in there, the task will get run and it doesn't halt the other scheduled tasks from running. There's also worker_ready() but that doesn't look at the upcoming task's arguments to do the check.
Database Lock (also here as well): I can have each of the tasks start running normally and then do the check at the beginning of the task's run but if I set a periodic interval to check if condition is met, I lose the order of the active queue as condition can be met at any point and one of the many active tasks will be able to continue. This is where the database lock comes in and is so far the most feasible solution. I can make a lock every time I do the check and if the condition's not met, it stays locked. When the condition's finally met, I release the lock for the next item in the queue, preserving the queue's original order.
I find it surprising that celery doesn't have this functionality to specify if/when the next item in the scheduled queue is ready to be run.

AnyLogic - transition triggered by a condition

i'm new to AnyLogic...but it is driving me crazy!!!
It is super basic...in an AB model I want a percentage of agents to go from one state to another...but it happens something that I cannot understand :S
I have 1000 agents...I expect 950 to go in state V3...yet
Only 889 agents change status :(
It seems that the condition is evaluated twice...indeed 0.95*0.95=0.90..that is exactly the percentage of agents changing status :(
Not satisfied I tried to put the contidion in the "guard"
and the result is perfect!!!
Can anyone help me understand this? :(
I have to revise the entire model...when do I have to put "conditions" and when "guards"?
Thanks everyone!!
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
from #sdaza model
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AnyLogic Support Team answer
_The condition is evaluated twice in case if it returns true initially. Initial chec is performed when agent enters in state that has outcoming conditional transition(s). If certain condition of a transition returns true, engine tries to trigger it. Here the condition is checked again. If the condition returns false, it will be cancelled, agent remains in the state. In other words, condition should return true twice to be executed.
In your case only the agents that returned "true" twice executed the transition, and probability matches with result: 0.95 * 0.95 = 0.9. This is actual probability.
I hope it will help_
I didn't get the reason why it is so though...
Some background and an example model which 'opens up' a bit what is happening behind the scenes should help you understand the AnyLogic response.
Background
AnyLogic conditions are checked at every step of the model (i.e., at model start and after every event created explicitly by the developer or implicitly via the AnyLogic elements used). AnyLogic also uses timeout 0 events under the covers to effect state transitions; i.e., if it decides a transition of any sort is due, it does not do it immediately but schedules an event for the same simulation time to do so, which will be triggered at the next step of the model if there are no other events at the same simulation time. If you have the Professional edition, you can see this at model runtime via the Events Viewer (see later).
Condition Transitions
Because of the above, the condition is evaluated at the start of the model. If it is true, a timeout 0 event is scheduled to effect the transition. When this fires, the condition is checked again (because it is possible it is no longer true due to intervening events at the same simulation time). If it is true this second time, the transition goes ahead.
Example Model
I adapted your example. I just have a Main with a statechart with two states and two transitions: a condition one (with your randomTrue(0.95) condition) from state 1 to state 2, and a timeout 1 one which sends state 2 back to state 1. By putting the condition inside a function (check), I can add some extra traceln statements so we can better see what's going on.
Run this (setting to Run Until time 0 so it pauses at model startup) with the Event Viewer shown. The condition evaluated true so you can see the timeout 0 transition event set up.
I also added some traceln messages for the condition transition occurring and the transition back to state 1. Here's a sample from a run. (The transitions will stop once the condition doesn't evaluate true twice in a row, and so will depend on the random seed chosen for the run.)
Checking condition at time 0.0: sampled true
Checking condition at time 0.0: sampled true
Probabilistically transitioned to state 2
Going back to state 1
Checking condition at time 1.0: sampled true
Checking condition at time 1.0: sampled true
Checking condition at time 1.0: sampled true
Probabilistically transitioned to state 2
Going back to state 1
Checking condition at time 2.0: sampled false
Checking condition at time 2.0: sampled true
Checking condition at time 2.0: sampled true
Probabilistically transitioned to state 2
Going back to state 1
Checking condition at time 3.0: sampled true
Checking condition at time 3.0: sampled true
Checking condition at time 3.0: sampled true
Probabilistically transitioned to state 2
Going back to state 1
Checking condition at time 4.0: sampled true
Checking condition at time 4.0: sampled false
Notice that there are three condition evaluations each time after the first transition. I presume this is because the condition is also evaluated when the state 2 --> state 1 transition event fires (after its action code completes but before the transition is actually completed). Whether it evaluates true or false at these points is irrelevant since the Agent is not in state 1 yet and so the state 2 transition is not 'active'. (This does seem slightly strange, since it would be more efficient for conditions only to be checked if the Agent is in a state where the condition transition is active. However, I have no other explanation for this extra evaluation otherwise.)
It then arrives in state 1 and so the condition is checked (immediately, without an event) and, if true, a state 2 transition event is setup (causing the second check when it fires).

Statechart definition of two "parallel" processes

I am trying to define two independent but related processes, criminal career and crime enforcement (imprisonment). Here is a diagram:
Crimes will be committed only if an agent has already started his criminal career through an internal transition. Desistance (to move away from crime) is a final state that can happen while an agent is imprisoned (that's why I define this problem as two independent processes).
When a crime occurs (internal transition commitCrime) the variable committedCrime is set to true. The commitCrime transition has as a guard this.ImprisonmentStateChart.isStateActive(Free), so an agent cannot commit crimes if he is imprisoned.
Every time a crime is committed, a condition transition is assessed from state Free: this.committedCrime == true. Once in prison, an agent will be eventually released.
My problem is that the commitCrime transition is not restarted after coming back to the Free state. The idea would be to restart the commitCrime transition after releaseFromPrison is triggered, but I haven't found how to do it with Anylogic 7.
Any ideas?
I think the simplest way is to remove guard and wrap the action in if statement:
if ( ImprisonmentStateChart.isStateActive(Free) )
committedCrime == true;

Quartz.net scheduler and IStatefulJob

I am wondering if I am understanding this right.
http://quartznet.sourceforge.net/apidoc/
IStatefulJob instances follow slightly
different rules from regular IJob
instances. The key difference is that
their associated JobDataMap is
re-persisted after every execution of
the job, thus preserving state for the
next execution. The other difference
is that stateful jobs are not allowed
to Execute concurrently, which means
new triggers that occur before the
completion of the IJob.Execute method
will be delayed.
Does this mean all triggers will be delayed until another trigger is done? If so how can I make it so only the same triggers will not fire until the previous trigger is done.
Say I have trigger A that fires every min but for some reason it is slow and takes a minute and half to execute. If I just use a plan IJob the next one would fire and I don't want this. I want to halt trigger A from fireing again until it is done.
However at the same time I have trigger B that fires every minute as well. It is going normal speed and finishes every minutes on time. I don't want trigger B to be held up because of trigger A.
From my understanding this is what would happen if I use IStatefulJob.
In short.. This behavior is from job's side. So regardless how many triggers you may have only single instance of given IStatefulJob (job name, job group dictates the instance id) running at a time. So there might be two instance of same job type, but no same-named jobs (name, group) if job implements IStatefulJob.
If trigger misses its fire time because of this, the misfire instructions come into play. A trigger that misses its next fire because the earlier invocation is still running decides what to do based on its misfire instruction (see API and tutorial).
With plain IJob you have no guarantees about how many jobs will be running at the same time if you have multiple triggers for it and/or misfires are happening. IJob is just contract interface for invoking the job. Quartz.NET 2.0 will split IStatefulJob combined behavior to two separate attributes: DisallowConcurrentExecution and PersistJobDataAfterExecution.
So you could combine same job type (IStatefulJobs) with two definitions (different job names) and triggers with applicable misfire instructions.