From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Best method to stop the loop inside Actor Core?

Hi all,

Recently I started using Actor Framework in one of my projects and I went through few examples from forums and the Actor Framework Template Project from LabVIEW(2014). I see there are two ways of terminating the while loop inside the Actor Core method.


Method 1 - From Actor Framework Template Project

     In the Actor Core method of this template, I see a hidden boolean control is placed on the Actor core and the Value signalling on this boolean control is used to terminate the while loop.

Method-1.png

Method 2- Examples from forums

     In few other examples, I see a user-event is being used to stop the loop as shown below

Helper-Loop.png

I need to know which is the best way to stop the loop inside the Actor Core method. Please help.

Thanks,

Sweatha


0 Kudos
Message 1 of 12
(6,927 Views)

There are several good ways to stop helper loops.  The "best" way is going to depend on your requirements.

Using a hidden Boolean control is perfectly adequate, but it's pretty light duty.  I'd save that for simple helper loops that aren't clocked by some reference-based mechanism (like a queue, notifier, or event structure).  If your helper loop is clocked by one of these mechanisms, then use that mechanism to cleanly stop your helper loop.

Clearly, the project template does not follow this advice.  Also clearly, we need to fix the project template.  If you're going to take on the coding burden of an event structure and user events, it costs very little to make a stop user event, as you saw on the forums.  The result will be cleaner and easier to understand.  (For the record, I don't like our project template for many reasons, and I don't recommend its use.)

Bonus:  Consider creating your user events in Pre Launch Init, and storing their references in the actor's attributes.  This will make them available in other actor methods.

Message 2 of 12
(5,997 Views)

Thanks for the advice Since I already use event structure in my helper loop, I will use the user-event to stop the helper loop.

One more concern I have is to decide if I need to store the user-event reference in the actor's attribute and over-ride the Stop-Core method just to trigger the user-event(as in the second image) or simply trigger the user-event from the Actor Core method itself like the one below?

Helper-Loop.png

0 Kudos
Message 3 of 12
(5,997 Views)

If you don't need to generate user events in your actor's method calls, you can keep the event creation/destruction on actor core's block diagram.  You only need to hold the event refnum in attributes if you want to invoke it in a method of the actor.  If you find you need to generate user events in your actor's methods, I'd recommend moving creation to Pre Launch Init and stop event generation and event destruction to Stop Core.

I tend toward using Pre Launch Init and Stop Core from the beginning, just because it's a fair bet I'm going to have other events eventually, but that's a personal decision.  Adding Pre Launch Init and Stop core take me less time than I will spend deciding whether or not I'm going to need them in the future.

0 Kudos
Message 4 of 12
(5,997 Views)

If Stop Core generates a user event and then destroys it, is there not a possibility of a race condition?

I've placed stop user event creation, generation, and destruction in each Actor Core VI because I was concerned that the event might be lost between generation and receipt of the event, or between receipt of the event and unregistering from it. I would certainly prefer not to clutter the Actor Core VIs with the stop event, but not if there's a chance one of them might generate an error or fail to stop.

I'm concerned also about stopping subclasses of the actor with the stop user event. If my base class creates a user event and provides a reference for subclasses to register for, might they fail to receive it when the base class itself generates, unregisters from, and destroys the event?

I just created a test case with a slow actor (5 second delay in an event handling loop in Actor Core) and a VI to create an event, pass the event ref to the slow actor, launch the slow actor, generate some events, and destroy the event before the slow actor has processed them all. It seems to work. The events wait in the slow actor's event queue even after the event has been destroyed. The user event refnum received by the slow actor is invalid once the event has been destroyed, but that is as expected.

I guess I've answered my own question already, but I'll post it in case I missed something or anyone else wonders the same thing.

0 Kudos
Message 5 of 12
(5,997 Views)

auspex wrote:

If Stop Core generates a user event and then destroys it, is there not a possibility of a race condition?

Nope.  R&D has confirmed that destroying a user event does not destroy unhandled events.  It destroys your ability to generate new ones, but any that are out there will still trigger events.

auspex wrote:

I'm concerned also about stopping subclasses of the actor with the stop user event. If my base class creates a user event and provides a reference for subclasses to register for, might they fail to receive it when the base class itself generates, unregisters from, and destroys the event?

Nope.  See above.  Also, event registration is specific to a given event structure.  If two event structures are registered for the same event (which is allowed), you can unregister for that event in one structure and not affect the other.  In your example, if the parent and child actors both had event structures registered for the stop message, they are both guaranteed to receive a stop event regardless of which structures unregister when.

Message 6 of 12
(5,997 Views)

Events are a lot easier want one realizes that the "User Event" is not the event, rather it is a reference to an array of event queues (the "Event Registration refnums").  Creating a User Event initializes it with an empty array; registering adds an event queue to the array; and generating an event increments over the array and generates events on each queue independently.  The "events" are actually just elements on the queue.  On the receiving end, the Event Structure is a means of pulling the next event from an array of 1 or more event queues.

Focusing on the event queues (Event Registration refnums) as the key thing, with User Events and Event Structures being means to access these queues, makes understanding Events much more intuitive.

0 Kudos
Message 7 of 12
(5,997 Views)

Untitled.png

Message 8 of 12
(5,997 Views)

Can you save that VI in LabVIEW 2016?  I don't have the 29th day build of 2017 yet

0 Kudos
Message 9 of 12
(5,997 Views)

Destroyed Events Are Still Received.png

0 Kudos
Message 10 of 12
(5,997 Views)