07-07-2026 11:00 AM
I would have thought the point of the tree is "the Caller is in control". The caller explicitly decides what messages to forward between subactors. Does your package have the Caller explicitly indicate which messages to forward, or does it blindly forward anything? If the latter then the Caller is just serving as a message broker and isn't in control.
07-08-2026 09:48 PM - edited 07-08-2026 10:02 PM
I'm one of the authors of the Zyah AF Msg Forwarding utility.
It does not break the messaging tree in the sense that all messages move up and down the tree structure as normal. All of the messages remain strictly typed as normal. Actors send their message using their caller's enqueuer just like normal, instead of somehow keeping track of one or more extra enqueuers that have been shared with them. The utility does not blindly forward all messages. Actors may register as a "source" or "sink" of specific messages, and then those specific messages will be forwarded through only the necessary parts of the actor messaging tree.
Conceptually it does "cheat" a little, in the sense that some actors may be forwarding messages up/down the tree without explicitly knowing what they are doing. Like Sam pointed out, knowing when to break the rules is important. I would not recommend using the forwarding utility in all cases, but I've found it to be very handy when doing things like passing data from DAQ actors on one side of a messaging tree to nested GUI actors on the other side of a messaging tree. It also allows you to implement slick plug-in architectures where you can dynamically launch producers and consumers of messages without intermediary actors in the messaging tree knowing who is running. Check out the blog post we wrote when releasing v3 of the utility for more details.
In the case of logging, that is one of the rare cases where I typically prefer skipping the messaging tree completely. Allowing actors to directly add events into the log is faster, and eliminates any issues that may arise if some actor in the middle of your messaging tree is backed up or not operating properly.
However you decide to implement the actual logging, I would make a protected method (e.g. "Write To Log.vi") in the "base" actor class that all of my other actor classes inherit from. Child actors can just use this method to write to the log, without needing to know how the method functions internally. Inside of the VI you can implement the logging using a shared enqueuer, a named queue, a DVR, sending a message to your caller, or whatever mechanism you want. If you decide later that you want to change how the logging is implemented, only your base actor needs to change. All of your other actors remain blissfully unaware that the lead developer refactored how logging works. Being able to inherit functionality like this is one of the most powerful aspects of AF in my opinion.
Hope that helps!
07-09-2026 11:08 AM
It does indeed, thanks! I was aware of the message forwarding utility but haven't had a chance to play with it yet as I haven't really needed it, but it's one of those things where I think once I understand it I'll be able to use it. It looked like a nice tool, but as you can see (by the existence of this thread, lol) I've been battling this sort of thing.
Most of the time, when I've forwarded messages through the tree, each "hop" does more than just blindly forwarding; they each reinterpret the message somehow, even if it's just converting "volts" to "pounds", or even "pounds" to "pounds on the main load cell".
Also, I read your update, and it clicked a bit better for me than the last time I looked into it. I think this could be pretty useful for sending configuration info around my whole Actor tree. Right now, I have a single giant JSON config file, each with separate sections that are decoupled from the rest, so each module can interact with it as needed, reading or changing values on its own. This works, but is sort of a "route around" the tree, in a way, since each item has direct access to the same file.
If I switched to a message handling system, I could replace my existing system with an interface-based system, and my individual Actors could just talk to a standard "read parameter" or "write parameter" interface, and I could switch to a database (or even multiple different sources) without my child Actors knowing.
(Of course I could do this with regular Objects, too, but this lets me use Actors which is nice if I need my config loader to have its own async process.)
08-05-2026 11:25 AM
Has anyone used 'Write to System Log.vi'?
I've always wondered why it was not more developer friendly. It writes to the Windows Event Log. The latter has some good built-in features - Configurable size, so that older records will get automatically purged; filtering criteria that can be saved.
Unfortunately, the said VI always identifies a message to be sourced as 'National Instruments' rather than the binary built according to the build specification.
08-05-2026 02:48 PM
The DLL it calls looks like it tries to set a different Event Source, but no matter what you wire there it always says "National Instruments". The "Source" field looks like it gets totally thrown out.
08-05-2026 06:37 PM
Ah, I did a little more research. It looks like you can't use custom Event Sources- you have to register all Event Sources first, which requires admin rights:
So, you could probably do that as part of an application installer, then write your own Event Log generator to call the NI dll. I guess that's why this one isn't particularly "developer friendly".
08-06-2026 01:52 AM
That explains it! Thanks for digging that up!
Inspired by Golang's log/slog package, motivated by this thread, and triggered by my colleague for a reusable library, I am implementing a (hopefully) simple approach: A Logger class that wraps an actor with one message - log. The format and destination are pure interfaces so that the log VI can invoke something like Formatter:format(logRecord), whose output is routed to Writer:write(string). To trap errors from the concrete classes that implement these interfaces, I've chosen to 'Write to System Log', a guaranteed destination. Logging levels DEBUG, INFO, WARN and ERROR are provided to filter the feed to the actor, via a simple comparison to the threshold level settable in the Logger class.
08-06-2026 05:59 AM
This could be of interest. Paul has accompanying videos that overview the composed systems logger:
- https://m.youtube.com/watch?v=LGqO59fT6lU (21:50)
- https://m.youtube.com/watch?v=FcmLEamr_EU&ra=m (32:29)
Different enum event types and filtering. Could give ideas through interface implementation.
08-06-2026 11:28 AM
This isn't an Actor, but it's a promising logging utility:
https://www.vipm.io/package/cyth_logger_sqlite/
It's a JDPowell tool and uses an SQLite database backend.