peper Posted October 5, 2021 Report Share Posted October 5, 2021 Hi all, I have this simple actor framework architecture where my root actor, called "controller", launches two different nested actors called respectively "reader" and "writer". Typically: "reader" acquires data from a DAQ "writer" writes the data to a TDMS file. "controller" sends the different commands to "reader" and "writer" (like start/stop acquisition or start/stop recording) and routes the data acquired by "reader" to "writer" "reader" and "writer" both send back their respective state to "controller" (like acquisition in progress, writing in progress,...) In order to decouple "reader" and "writer" from "controller", I mimiced the LV2020 shipping example (Actors and Interfaces) and created an interface for "writer' and "reader" (one interface per actor). I then made "controller" inherit from both interfaces. Then, in each interfaces, I created a method called "UpdateStatus" and created the messages that will be sent by "reader" and "writer" to "controller" The problem is that the "UpdateStatus" methods do not have the same connector panes in the two interfaces and hence LV tells me that I have an error. One obvious fix would be to have different names for the methods of the interface ("UpdateReaderStatus" and "UpdateWriterStatus" for instance) but it is not always possible. Am I missing something? Because it seems that AF modules programmed with the interface technique will be difficult to reuse if rmethods renaming is necessary. Thanks in advance for your comments! Regards, Quote Link to comment
dhakkan Posted October 5, 2021 Report Share Posted October 5, 2021 (edited) Per my understanding, having two separate names is required. Changing the name of the VI publishing the data to the caller ("reader" in your case) to an announcement that the action has been completed, will likely make your communication semantically meaningful. E.g. Reader's announcement via the interface could be "dataPacketAcquired" or equivalent. When Controller implements this method, it will request the Writer to 'updateStatus', as you currently have. In general, a mantra I've been following is: Nested1 -> eventOccurred -> Caller -> doSomething -> Nested2. Edit (an hour later): Also., from a design perspective, your Controller should NOT be implementing (inheriting) the updateStatus capability - that rests with the Writer. Edited October 5, 2021 by dhakkan Addressing another point Quote Link to comment
peper Posted October 5, 2021 Author Report Share Posted October 5, 2021 (edited) Hey, Thanks for your reply. I do agree with you that choosing very specific names for the methods lower the risk of name "conflict". However, in a scenario where actor framework modules would be reused in different projects by different programmers, over a long period of time, it is difficult to enforce that. Moreover methods name will probably become quite long and LabVIEW doesn't like that. I think developers will be tempted to use much shorter and generic names for the methods, like in the example below: "Controller" inherits fom "ReaderMsgReceiver" and from "WriterMsgReceiver" both interfaces declaring a generic "UpdateState" method but with different connector panes. This method basically informs the "controller" of the state of the "writer" and "reader" modules. Note that the concrete "reader" and "writer" modules are not present in this example for the sake of clarity (not sure if it's clearer though:)). They will use the "send" method of the "UpdateState Msg.lvclass" and "HandleDataPacket Msg.lvclass". I have attached the code and indeed LV mentions a connector pane conflict, which makes sense. I don't really see an easy fix for that situation... suggestions are welcome Thanks Regards EDIT: re-reading your answer I am not sure I'm following you on this: "Also., from a design perspective, your Controller should NOT be implementing (inheriting) the updateStatus capability - that rests with the Writer." Could you elaborate? Besides I have also attache an example with the concrete reader and writer modules with some comments. ActorTestInterface.zip ActorTestInterface (with concrete actors).zip Edited October 5, 2021 by peper Quote Link to comment
dhakkan Posted October 6, 2021 Report Share Posted October 6, 2021 13 hours ago, peper said: EDIT: re-reading your answer I am not sure I'm following you on this: "Also., from a design perspective, your Controller should NOT be implementing (inheriting) the updateStatus capability - that rests with the Writer." Could you elaborate? I misread and misinterpreted your usage of the 'UpdateStatus' message in the Writer - I thought that you were looking to 'write' the status value of the Reader's UpdateStatus into the TDMS file using the Writer's UpdateStatus message. Looking at the pictures above; the code samples, and re-reading your OP, it's clear now that you want both nested actors to apprise the caller of their respective status. My comment is totally invalid. Regarding your primary issue though, You could break up UpdateState.vi into the names you already indicated. E.g. Acquiring.vi; Writing.vi, etc. This way, the messages will not have any additional inputs in the connector pane; and the Controller will know exactly what to do when it receives a specific status message, without the need for case-structuring. (With UpdateState, I assume that you would need to case out your next action in the Controller based on the input state value.) From a reusability perspective, one could end up with a similar, if not same, problem if multiple nested actors of the same class are sending their status to the Caller. E.g. If using multiple Writer actors to write to TDMS files concurrently, how would the Controller know which nested Writer is reporting its status; unless the status message includes some form of identification of the nested actor (say nested-actor's enqueuer). I encountered a variant of the problem you posed, whereby I made various instrument actors (PowerSupply, Chiller, VacuumController, etc.) implement a Connectable interface with messages for connect and disconnect. That was easy. But, when I wanted to convey their status - connected and disconnected - to the caller, I was stuck. I ended up following a bit of advice from another post (can't find it now). The gist (as I understood it): the caller 'trusts' that the nested actor has performed the requested action. If the nested actor has not, it will send a well-defined error report. Exception handling is then done according to the problem domain. As a result, I didn't use 'connected' and 'disconnected' type state messages any more. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.