Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Stopping multiple helper loops with one user event

Ah, found the Help document that describes this behavior:

 

https://zone.ni.com/reference/en-XX/help/371361K-01/lvhowto/reg_event_foreach_es/

 


If you wire the event registration refnum to more than one Event structure, each Event structure handles dynamic events out of the same event queue. This can occur if you branch the event reg refnum out output of a Register For Events function to another Event structure. This causes a race condition, because the first Event structure to handle the event can prevent the other Event structure from receiving the event if it completes the event case before the other Event structure executes.


(Emphasis mine)

 

If I read this right, it's saying that both COULD get to it, but the event isn't removed from the dequeue when the case STARTS but when the case FINISHES. This means that two loops CAN grab the same event, but might not if one finishes before the other one can catch the event.

Message 11 of 31
(4,703 Views)

Interesting, it looks like if they're both waiting for the event they can both get it.... but sometimes only one does.

 

Still reinforces the concept of having separate registrations per event structure.

Craig H. | CLA CTA CLED | Applications Engineer | NI Employee 2012-2023
0 Kudos
Message 12 of 31
(4,694 Views)

Thank you for all the answers! Seems that I was not the only one not knowing how this works.

 

Then another question.

On earlier experiments I used lot of state machines which has while loop with shift registers and case structure.

If I have this kind of structure, would this also require register for every case structure also?

 

The wrong way presented in the pictures?

Two states which both connected to same register?

Waltteri_1-1612424177322.png

Waltteri_0-1612424150150.png

If I really need this then it should be like this?

Waltteri_2-1612424643097.png

 

 

Actor framework is "easy" when you just wait for user inputs like buttons to be pressed. With UI that has lots of components that needs to be enabled/disabled/background color changed etc. according users actions and some measurements, it gets tricky. That kind of state machine would make it easy, but then again dynamic stop event makes life hard if there are lot of states.

 

0 Kudos
Message 13 of 31
(4,671 Views)

Dynamic events are new thing to me and I just realized that I'm trying to catch and handle all of them in actor core. But if I run another Vi with while loop and event structure I can caught and handle the dynamic event there?

0 Kudos
Message 14 of 31
(4,655 Views)

@Waltteri wrote:

Then another question.

On earlier experiments I used lot of state machines which has while loop with shift registers and case structure.

If I have this kind of structure, would this also require register for every case structure also?

 


Instead of event handlers inside cases of a case structure on State, consider a single event handler, with case structures on State inside that.

 

So, in words, rather than what you have:

Given State 1

--When Event X happens do Y

 

Have

When Event X happens

--If in State 1 do Y

 

This is the way it is more commonly done, I believe.  It makes events that apply to many or all states (like your stop event) easy.

0 Kudos
Message 15 of 31
(4,649 Views)

I created a new vi from static dispatch template.

It has while loop and event structure with three events. Two other events are working but the Stop is not working. When I stop the actor core, this Vi keeps on running.

Any ideas why is that?

Waltteri_1-1612436830661.png

 

0 Kudos
Message 16 of 31
(4,637 Views)

@Waltteri wrote:

I created a new vi from static dispatch template.

It has while loop and event structure with three events. Two other events are working but the Stop is not working. When I stop the actor core, this Vi keeps on running.

Any ideas why is that?

Waltteri_1-1612436830661.png

 


Are you sure, the events have been unregistered only after your event loop is ended? Maybe the root "race-condition-ish"

0 Kudos
Message 17 of 31
(4,632 Views)

What is the visibility of the stop event?

 

I mean if I have nested actors in array and when I send the stop event to all of them, should they all unregister the event that they receive or is it the same event for everyone?

 

0 Kudos
Message 18 of 31
(4,605 Views)

1.) Where / in which function does your Actor send the Stop event to the helper loop?

2.) When do you unregister the events/ destroy the event ref  for the stop event for the helper loop? If you do this immedeatly after firing the stop event it might not be recieved by the event case. If so, sending a different event (which usually works) instead of a stop from the same location withinin your code will also fail.

 

You might also want to check https://youtu.be/F8DiZrDcres?t=1305

 

0 Kudos
Message 19 of 31
(4,599 Views)

@Waltteri wrote:

Thank you for all the answers! Seems that I was not the only one not knowing how this works.

 

Then another question.

On earlier experiments I used lot of state machines which has while loop with shift registers and case structure.

If I have this kind of structure, would this also require register for every case structure also?

 

The wrong way presented in the pictures?

Two states which both connected to same register?

Waltteri_1-1612424177322.png

Waltteri_0-1612424150150.png

If I really need this then it should be like this?

Waltteri_2-1612424643097.png

 

 

Actor framework is "easy" when you just wait for user inputs like buttons to be pressed. With UI that has lots of components that needs to be enabled/disabled/background color changed etc. according users actions and some measurements, it gets tricky. That kind of state machine would make it easy, but then again dynamic stop event makes life hard if there are lot of states.

 


Neither of those are good solutions. While I *think* the first method would work, since only one structure is called, it's going to be VERY hard to ensure nothing gets stepped on. The thing with user event queues is that they're not really queues (like you've seen discussed). When you only have one handler, it's fine to think of it that way, but with multiples it's not a good idea. You still have two handlers tied to the same RfE node, and you might one day find that the handler for state 1 still thinks it needs to handle a case even though it was sent when state 2 was active.

 

Your second method is extra bad, as you will queue up unhandled events while you're in State 2. When you go back to State 1, all of those events will spill out at once.

 

The right way to do it is to handle state *within* the handler, not externally to it (like drjdpowell said).

 

Regarding your Stop case not working. This code looks like you might have done something wrong. The fact that you have your Actor coming in AND coming out means you've likely split your Actor wire. Helper loops should read references only. What are you doing with your Actor output?

0 Kudos
Message 20 of 31
(4,573 Views)