How Do I get next state/event in Spring state Machine - spring-statemachine

1) I am processing a particular event from the transition, how Do I get the info about next event?
2) If I need to stop the transition from one state to another during the transition action, how Do I do that?

1) I'm guessing your processing code runs in a transition's action.
You can get from the provided StateContext the source state, the target state, and the event that caused the transition.
You can't possibly get the next event, because it wasn't sent yet.
2) I don't think that's possible.
If the transition action might fail and it means that in this scenario you should go to an altogether different state - then you should redesign your statemachine to run this code from somewhere different than the transition action.
For example from the state's action, and send a different event based on success/failure.

Related

Spring Statemachine: how to handle two transitions that has the same source state?

How does Spring Statemachine handle two transitions that has the same source state?
For example:
Source State: ready
Event: start
One transition will be lead to the target state running, another one will be failure
Any help would be appreciated.
the scenario you described above can be achieved in two ways.
In case of failure to process the incoming event (START), machine would remain in the original state (ready). The transition is only completed when event is process successfully.
However, if you really need to get away from READY state and move to RUNNING or FAILURE, one can use the Guard condition. You can use an evaluation function to define if the START event was successful or not and define to which state machine should go to.
This can be achieved using a CHOICE pseudo-state that is protected by a Guard class, based on machine configuration and Guard evaluation, machine would move to the expected state
The official doc for reference on how to make the implementation is here

How to check if the event triggers the state machine in Spring Statemachine?

Let me summarize my question as follows,
I know that the stateMachine.sendEvent(Event e) returns a boolean value representing if the event triggers a transition or not, but it also triggers the transition if true.
However, I want only to check if the state machine is triggerable by that event or not, and not to trigger the transition afterwards. Is there any way to do that?
There is no built-in method to do that, but once you retrieve an instance of a StateMachine, you can implement a method to iterate over the transitions looking for the current state and check what are the available transitions for that state. Each AbstractTransition contains a source and target state
machine.getTransitions()

How to ignore events in LabView triggered outside of a particular sequence frame?

Using event structures in LabView can get confusing, especially when mixing them with a mostly synchronous workflow. My question is, when an event structure exists in one frame of a sequence, how can I force it to ignore events (e.g. mousedown on a particular button) that were triggered while the workflow is in another frame of the sequence?
Currently, the event structures only process the events at the correct frame in the sequence, but if one was triggered while the workflow is in the previous frame, it processes those too and I want it to ignore any events that weren't triggered in the frame that the event structure exists within.
http://puu.sh/hwnoO/acdd4c011d.png
Here's part of my workflow. If the mousedown is triggered while the left part is executing, I want the event structure to ignore those events once the sequence reaches it.
Instead of placing the event structure inside your main program sequence, put it in a separate loop and have it pass the details of each event to the main sequence by means of a queue. Then you can discard the details of the events you don't want by flushing the queue at the appropriate point.
Alternatively you could use a boolean control to determine whether the event loop sends event details to the queue or discards them, and toggle the boolean with a local variable from the main sequence.
You can register for events dynamically. Registration is the point in time at which the event structure starts enqueueing events, and in your case this happens when the VI the event structure is in enters run mode (meaning it's executing or one of its callers is). You can change it so that you register using the Register for Events node and then you would only get events from that point on. When you unregister you will stop getting events.
There's a very good presentation by Jack Dunaway going into some details about events here.
You can find the code for it here.
In LabVIEW 2013 and later there are additional options for controlling the events queue, but I won't go into them here.
http://puu.sh/hwsBE/fe50dee671.png
I couldn't figure out how to flush the event queue for built-in event types like mousedown, but I managed to get around that by creating a static reference to the VI and setting the cursor to busy during the previous sequence, disabling clicking. Then when the sequence for the event structure is reached, I unset the cursor from busy, which re-enables clicking.

Eventbus event order

Morning,
I'm using the SimpleEvent bus to send data from my centralized data reviver to the Widgets. This works really fine, I get one set of new Data form the server, the success method of the RPC call puts it on the Eventbus, each widget looks if the data is for it, if yes it 'displays' it, if not, it does nothing.There is only one data set per request and the widgets don't depend on other data being already sent.
Now I have a Tree widget. The child nodes of the Tree are created throw this data sets too, and this child nodes register itself to the Eventbus to revive the data for their child nodes. The data shall be received in on rush (for performance reasons obv), so I will get multiple data sets which are put on the Eventbus at the 'same time' (in a for loop). I only control the order in which they are put there (first the root, then the data for the first child......). How does the Eventbus now proceeds the events?
Does he wait till the first event is completed, so the first child of
the tree already finished creation and register itself to the
Eventbus, to revive the data to create it's child's.
Does he handle them simultaneous, so a widget isn't even registered to the Eventbus.
Does he mix up the order?!?!
Current solution approaches:
The best solution I can think of, is to only put new events on the
Eventbus when the previous got completed. However I found a method
which does so, or if it is the standard behavior of the Eventbus .
Fire a request processing finished event, when a event was processed by a widget. Yucks... this leads to a lot of additional code and causes big problems, when data is put on the Eventbus which doesn't belong to any widget....
Register a static variable which is set to true when the request got handled and the Eventbus waits this long till he puts the next request on the Eventbus (Quiet similar to two, but way worse coding style and the same problems)
All events are handled by the root tree element, which sends them upwards to the respective child's.
Which solution would you prefer and why?
Regards,
Stefan
PS: my favorite answer would be that 1. is the standard behavior of the Eventbus^^
PPS: The solution should also be working on when introducing Webworkers.
The EventBus#fireEvent is synchronous. It's by design. You can pass an event to the bus, have handlers possibly modify it, and when execution returns to your method you can check the event; this is used for PlaceChangeRequestEvent and its setMessage for instance.
FYI, if a handler throws an exception, it won't prevent other handlers from being executed. The fireEvent will then wrap the exceptions (plural; several handlers can throw) in an UmbrellaException.
Although EventBus is a nice way of de-coupling parts of your application it doesn't mean it should be "overused".
I also think you should be careful not to circumvent the asynchronous behavior of your client-side code by introducing synchronous/blocking like behavior.
Javascript is single threaded so I don't think you can have two events at the same time. They will be executed one after the other.
If you fire an event on the EventBus (i.e. SimpleEventBus) it will just iterator through the list of attached handlers and execute them. If no handler is attached nothing happens.
I personally would prefer the 4th. approach especially if you plan to use a CellTree some time in the future. The Tree widget/CellTree widget handles the event and constructs its structure by traversing through the object.

What is the best way to save the environment from before an alarm handler goes off when the alarm does goes off?

I'm trying to implement user threads on a 2.4 Linux kernel (homework) and the trick for context switch seems to be using an alarm that goes off every x milliseconds and sends us to an alarm handler from which we can longjmp to the next thread. What I'm having difficulties with is figuring out how to save the environment to return to later.
Basically I have an array of jmp_buffs, and every time a "context switch" using the alarm happens I want to save the previous context to the appropriate entry of the array and longjmp to the next one. However, just the fact that I need to do this from the event handler means that just using setjmp in the event handler won't give me exactly the kind of environment I want (as far as stack and program counter are involved) because the stack has the event handler call in it and the pc is in the event handler.
I suppose I can look at the stack and alter it to fit my needs, but that feels a bit cumbersome. Another idea I had is to somehow pass the environment before the jump to event handler as a parameter to the event handler, but I can't figure out if this is possible.
So I guess my question is- how do I do this right?
You should be able to just do something like:
if (setjmp(&from_thread))
return;
else
longjmp(&dest_thread, 1);
in the event handler. Sure, it means it'll arrive back in the thread in the event handler - but that's OK because then you'll return straight out of it, so it'll go back to where the thread was when the event handler triggered.
(Of course this presumes that you've set up separate stacks for the threads already).

Resources