Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Best practice for altering state of actor from its helper loop?

Solved!
Go to solution

@WavePacket wrote:

If I rephrase this to check my understanding, what you are saying is that:

1. root will receive the message from nested prelaunch init

2. root method fires a user event (for which an event structure in root's helper loop is dynamically registered for)

3. then potentially right way, or sometime later, when root's helper loop is up and running, that user event will be handled. No event is lost b/c the loop isn't running yet.

 


As long as the Event Registration node is upstream (through the error cluster) of the Call Parent Class Method node in Actor Core, yes.

0 Kudos
Message 11 of 28
(4,574 Views)

@AristosQueue (NI) wrote:

@WavePacket wrote:

If I rephrase this to check my understanding, what you are saying is that:

1. root will receive the message from nested prelaunch init

2. root method fires a user event (for which an event structure in root's helper loop is dynamically registered for)

3. then potentially right way, or sometime later, when root's helper loop is up and running, that user event will be handled. No event is lost b/c the loop isn't running yet.

 


As long as the Event Registration node is upstream (through the error cluster) of the Call Parent Class Method node in Actor Core, yes.


Sorry to be really specific (I'm learning these details). Should I also infer that if the Event Registration node is not upstream but free floating, that losing an event is a possibility? What I'm also inferring is that the event registration node stores user events almost like a queue and the event structure dequeues the events when it has availability. This is probably all pretty basic stuff.


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 12 of 28
(4,569 Views)
Solution
Accepted by topic author WavePacket

Event registration node is the thing that says, "I care about events from these event refnums." Any event that fires after registration is caught, even if the Event Structure itself isn't yet running. Any event that first before event registration is lost. Thus you have to make sure that the Event Registration node executes before the thing that will call Generate User Event. In this specific case, that means making sure Event Registration is upstream of the Call Parent node.

0 Kudos
Message 13 of 28
(4,561 Views)

So the sequence is:

 

  1. "Launch Root Actor" (safe to send messages to root actor after this point)
    1. Root actor's "Pre Launch Init"
  2. Root actor's "Actor Core". In parallel:
    1. "Launch Nested Actor" (safe to send messages to nested actor after this point)
      1. Nested actor's "Pre Launch Init"

and

    1. Register for events for parent helper loop (safe to generate user events after this point)
    2. In parallel:
      1. Call Parent Class Method node
      2. Start helper loop

Suddenly I remember why this is a graphical language. 🙂

0 Kudos
Message 14 of 28
(4,553 Views)

Sounds good. I'll presume that if my inter-loop communication process is a queue instead of events, that the same potential race condition exists and I should create the queue upstream of root's Call Parent Class Method node.


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 15 of 28
(4,532 Views)

@WavePacket wrote:

Sounds good. I'll presume that if my inter-loop communication process is a queue instead of events, that the same potential race condition exists and I should create the queue upstream of root's Call Parent Class Method node.


If you use Events, then you have a few bits:

  1. Create User Event (gives ref)
  2. Register User Event (needs ref)
  3. Generate User Event (needs ref)

So you must do (1.) first, but probably you're placing that in the private data and unbundling, or creating before Call Parent Class Method and bundling first? In either case, it's almost guaranteed you'll have it available in time, the earlier parts of this thread discussed the timing of (2.), critically that you must use it before a given Event, for the specific Event Registration Reference created to be triggered by that occurrence of the Event.

 

With Queues, instead you have

  1. Obtain Queue (gives ref)
  2. Enqueue Element (needs ref)
  3. Dequeue Element (needs ref)

If you're treating the queue reference in the same way as the User Event Refnum (not the Event Registration Reference), then the same is true, you'll almost have to create it first for it to be valid. Otherwise, you'll get Error 1 (invalid reference) at either (2.) or (3.). It's not possible to Enqueue to a queue, and not be able to dequeue the (same) element if you have a valid reference, because there's no registration step here.

Conversely, it is possible that if you pass the reference to the queue to multiple places, someone/where else might dequeue it, in which case it might never arrive (so don't do this, probably)


GCentral
Message 16 of 28
(4,522 Views)

@WavePacket wrote:

 

What I'm also inferring is that the event registration node stores user events almost like a queue and the event structure dequeues the events when it has availability. This is probably all pretty basic stuff.

Events are actually very straight forward and simple, but unfortunately it can take a long time to get an intuitive understanding.  I think it was a design mistake in the API that the most central component, the Event Queues, is only weakly referred to via the Event Registration Refnum wire.  This leads people to have a hard time understanding the more visible parts like the Event Structure (which is just a dequeue node).

Message 17 of 28
(4,509 Views)

@drjdpowell wrote: I think it was a design mistake in the API that the most central component, the Event Queues, is only weakly referred to via the Event Registration Refnum wire. 

It's definitely a weak spot, but I wouldn't call it a mistake as we wracked our brains for a year trying to find a different pattern that got anywhere near the efficiency and understandability of the current one. The current API pattern is at least explainable. Some of the ideas on the table for avoiding this hole were fairly arcane. Two that I remember (it was during my first year on LV team 21 years ago):

  • At the "Create User Event" node, a required input for "how many listeners will there be?" so we could start queuing up events right away... that defeated several useful dynamic registration patterns.
  • Giving "Create User Event" a required input "milliseconds to hold events" so that they would be queued up for some amount of time just in case a new event structure registered for them during the window.

There were many other variations workshopped. In the years since, I've never heard a better proposal.

0 Kudos
Message 18 of 28
(4,483 Views)

@AristosQueue (NI) wrote:

  • Giving "Create User Event" a required input "milliseconds to hold events" so that they would be queued up for some amount of time just in case a new event structure registered for them during the window.

You're making the same mental errors and trying to layer overly complex duct tape on top to "fix" them.  "Create User Event" is not the primary node to think about, and event structures don't register for events.  The key first node to understand is "Create Event Queue" which is the analog of "Create Queue".  Unfortunately, "Register For Events" does double duty as the creator of the Event Queue (by leaving the event reg refnum input unconnected), and the existence of this queue is only obliquely referred to in the documentation.

 

This immediately sets a new User up for loads of problems, as they try and understand the Events system without being aware of the central primary component.  They split the event registration wire to multiple structures (because they don't realize that it is a by-ref queue they have created), or they wonder when the Event Structure will "start listening for events" or why the UI gets locked when their event structure is not executing (because they don't realize the Event Queue is an independant thing with its own lifetime, even the Static ones associated with individual Event Structures).

 

Eventually, they hopefully get to the point that WavePacket has reached, of wondering if maybe "event registration node stores user events almost like a queue and the event structure dequeues the events", but this is really a big waste of time that could easily be avoided by not making the existence of the Event Queue so hidden.

0 Kudos
Message 19 of 28
(4,477 Views)

jdpowell: All the objections you just raised are known and were discussed during the design of the feature. Many alternatives were considered and rejected. I only enumerated two of them as "for examples".

0 Kudos
Message 20 of 28
(4,471 Views)