I am doing a project about data aquisition and data processing. Here is the hierarchy. I have to send some parameter configuration from controller to data aquisition and data process actors. So I have the question about sending message to different actor. And the data acquisition and data process hierarchy must be like the picture. So is there any good solution? or is there any actor framework pattern for data acquistion and data process. I really worried about the data or message sending for very deep hierarchy. Or actor framework is not suiable for deep hierarchy?
Solved! Go to Solution.
I think what I might do is restructure the hierarchy a bit. I would have a supervising actor (controller?) That knows about the acquisition and processing that needs to be done.
The controller would launch an acquisition actor, who would send it's data to the controller. The controller would also launch the data display and all the process actors.
You could configure the process actors with a Q to send it's data, instead of the controller needing to receive and pass the processed data to the next process step. So the controller would give process 1 the queue for process 2, process 2 the Q for process 3, etc. For the last process step you can give it the controller Q. This way you could add a process step in the future without needing to change any of the other process actors. You would just have the controller launch it and adjust the Q's to add it to the pipeline.
In the end, the controller will receive the acquired data and can pass it to the data display as well as the first process step. It can also send the finished processed data to the data display.
Hope this makes sense.
Thanks a lot. That is the one I think about at first. I did not get how to pass data from process 1 to 2, 2 to 3 etc. you mean controller give a Q to them. Is that a same enqueuer? If so, it is not a pipeline process anymore. Could you give me more detail about Q?
You would have an actor queue (call it the Send Queue) in the private data of each processing actor with an accessor to set this queue. If you have four processing actors the controller actor would:
Each process actor doesn't know where the Send Queue goes, just that it needs to send the data on this queue. To kick off the process pipeline, the controller would send the acquired data to process 1. The process chain will run and you'll receive final data from process 4.
Tried to create a quick diagram to explain a bit more:
This hierarchy seems to me also more natural. But, You do not necessarily have to break the AF standard communications path. You can override Controller's Receive Message.vi in the following way:
Root equals Controller in my case.
For process N you need to define an intermediate class. e.g. Msg for Process1.lvclass inheriging from Message.lvclass. If you now create a message for Process 1, you only need to change the parent class from Message.lvclass to Msg for Process1. The class hierarchy of the messages looks like this:
At last step You need to create a map between you process and message base class, when You launch the nested actors:
Now You can just send desired message from one nested actor to another one via the root (contoller):
The rest is done by the contoller::receive message.vi.
That is useful. Thanks for your detail. However, in my project, I don't want to send message via root actor because process actor 1,2,3,4 build a pipeline system. If via root actor, the efficiency will decrease, right?
I pipeline data between actors using standard queue's that I create on the fly. I use actor messages only for configuration of the asynchronous processes. The actor cores of the pipelined actors enqueue / dequeue the data, perform whatever action they do, then re-enqueue down the pipeline. I have to do it this way because I'm pushing around a lot of data at pretty quick rates (100 Hz message rates).
Going around the AF messages can certainly be done but I've always read it's a bad idea due to difficulty debugging.
If I had an actor I wanted to pipeline, I'd give it a "Next pipe" enqueuer reference as its private data that gets set in its launcher. Don't forget, Actors are still Objects, and you can call methods directly on their reference wire before they get launched by Launch Actor. If you need to change destinations after launching, use another message.
When it's done with its processing, it fires the data out to the "Next pipe" AF enqueuer.
This still goes around the "standard" AF tree structure, but I think you gain some benefits of using the AF message structure instead of standard Queues. Just my preference though.