05-06-2022 12:06 PM - edited 05-06-2022 12:07 PM
My team and I are having a debate about how to send data to other actors and I'm curious what others here think.
Here's the (generalized) scenario:
How should the Data Aggregator actor distribute the CVT data to these other actors? Here are two options we're considering:
Option 1 doesn't involve any data transport mechanism other than AF messages and the direction of messages to consuming actors can be made easier via tools like the (shameless self plug incoming) Zyah AF Forwarding Utility, but involves many more messages and copies of data.
Option 2 eliminates most of the messages to the data consumers, but at the expense of "shortcutting" the AF message tree. It also (arguably) simplifies the handling of data on the consumer side - actors only use the class to read the CVT when they want to use the data rather than having to deal with extra incoming messages.
How would others resolve this issue? Perhaps there's a 3rd option that's even better?
05-09-2022 04:10 AM
Does your Data need to be lossy? Or does just your display updates need to be lossy? Getting new data at 100 Hz doesn't mean you have to update the display at 100 Hz.
05-09-2022 05:04 PM
05-09-2022 05:15 PM
Keep your life simple. Option 2.
Just have your aggregator throw all the data into a DVR and each process pulls out what it needs when it needs it.
05-10-2022 01:27 AM
In the View is the natural place for logic about how often to update the view. Just record the latest value and update the UI whenever. This doesn't violate the Actor Model; the only concern would be excess overhead of extra messages.
Note that if you share a DVR you give up the ability to host your UI actor on a different computer to your data producer. You also get the potential for race conditions between the DVR poll and incoming messages. None of this may matter but it is a concern and I'd say this is actually the more complex option, even if it seems simple.
05-10-2022 01:48 AM
This reminded me of this suggestion I made: https://forums.ni.com/t5/Actor-Framework-Discussions/Suggestion-a-Queue-Empty-overridable-method/td-...
This would allow a very easy way to have lossy updates of the UI. It's a technique I use in Messenger Library all the time and is simple and robust (robust as it throttles itself a best-possible UI update rate, rather than failing if it can't keep up with a set rate).
05-10-2022 10:15 AM
@drjdpowell wrote:
This reminded me of this suggestion I made: https://forums.ni.com/t5/Actor-Framework-Discussions/Suggestion-a-Queue-Empty-overridable-method/td-...
I hadn't see that before but I like the idea.
05-10-2022 10:25 AM
@Taggart wrote:
Keep your life simple. Option 2.
@drjdpowell wrote:
Note that if you share a DVR you give up the ability to host your UI actor on a different computer to your data producer. You also get the potential for race conditions between the DVR poll and incoming messages. None of this may matter but it is a concern and I'd say this is actually the more complex option, even if it seems simple.
We're not concerned with the ability to host the UI actor on a different computer in this case, but it's funny - you guys have stumbled into the same debate our team was having - is the DVR actually simpler?
About the race condition, I don't quite see where it comes into play. If you're reading from the DVR in the payload method of your incoming messages, you'll always be acting on the most recent data. On the other hand, using the message approach we'd end up updating the same data internally in the view/logging actors and then I can see a race condition with regards to whether or not the incoming messages are acting upon the very latest data.
05-10-2022 09:53 PM
As a modification to option 1, you could have the subscribe method start a time-delayed send message to self (Aggregator Actor) with the subscriber's enqueuer stored in the message data.
Then you don't need factors/multiples/coercion. Just when the Aggregator receives the self-sent message, take the current values and the bundled (in message data) enqueuer and send the update message.
05-11-2022 12:11 AM
@cbutcher wrote:
As a modification to option 1, you could have the subscribe method start a time-delayed send message to self (Aggregator Actor) with the subscriber's enqueuer stored in the message data.
Then you don't need factors/multiples/coercion. Just when the Aggregator receives the self-sent message, take the current values and the bundled (in message data) enqueuer and send the update message.
+1 for this approach, especially if the data volumes are large. As an AF newbie, and being particularly excited about usage with LV2020 via interfaces, I just drew up a quick project (attached) last night with one measurement, to better understand the OP situation.
On the other hand, if RAM is not an issue, the raw data could directly be forwarded to the data consumers; and each can adjust the down-sampling as desired.