Great video Tom... You will probably get about 10 views from me just trying to wrap my head around the Actor Framework! But seriously, this series is one of the best I have seen on the subject. Thank you!
This is a great tutorial. Would love and so greatly appreciate if you could make more videos targeting data acquisition, measurement and testing, etc. examples (i.e. things LV was designed for). For instance, how can one incorporate file I/O, signal processing functionality, dynamic data visualization, etc.
Hello Tom! Firstly I wanted to thank you for the great contribution you are making with this TH-cam Channel. As LabVIEW developer, I really enjoy your videos. I wanted to make you a kind suggestion. I think that a short video explaining how to pass the CLA Exam based on an AF approach would be really useful for everyone willing to obtain such certification. Indeed, I think that it could be a good example to show the AF capabilities and how it can be used for architecting real applications.
Hi Victor, thank you for the feedback :) I'm not sure about creating a video specifically about passing the CLA because I want to teach developers how to AF properly as opposed to 'giving the answer' - but I'll look for further feedback to see if people would like an AF CLA 'master class'. While we're at the point in the AF series where I'm still explaining the basics of design, overrides, and implementation I wanted to stick to a really simple example (chat room). However, once all the basics are out of the way, I was thinking about writing a fully functional CLA paper (Elevator sample paper) in AF which I would do a code review video on. How does that sound? Please keep the feedback coming.
Hi Tom! Thank your for your quick reply. Of course, I understand that as now you are introducing the AF basics it's a bit soon to consider a more complex case as a AF CLA. So, I agree with you that the best moment to think about it is once all the fundamentals have been introduced. From my point of view, what I think it's really useful is to understand how an application can be divided into separate modules (Actors in this context) and how those modules are related according to a tree-structured hierarchy. So my idea is not about showing how to face a specific exam and where to place its covers but to show how (and why) a "Template AF Architecture" is designed in a way that makes it applicable not only for one specific case or exam but for a variety of them. In that case, it could be considered as a starting point, like a project template. In other words, I would say that the goal shouldn't be learning to solve one single exam but learning to think as a LabVIEW Architect using the AF. Please, let me know if you consider this approach interesting. Of course, I offer you my help if you think it could be useful in any way. Despite this, if you think it's better to focus on a specific case (like the Elevator exam AF-solution) and to do a code review video it will be great and really appreciated as well. I will be happy to read your feedback.
It's an interesting one that's difficult to explain. For example, when learning about the humble state machine, it was difficult to know what constituted an individual state, then moving onto classes, knowing what classes should be made, and now with actor, you need to be able to define individual processes*. Once, the AF basics are out the way, I could take a CLA requirements specification and treat it like a customer's brief, then do an AF design video where I talk about my thought/design process. It will probably be a couple of months before I have time to do that as I have courses to teach / presentations to write (CLA Summit in Krakow this year!) - as well as a full time job! *Just remember with software design - Good judgement is only made from making lots of bad judgements! ;)
@@TomsLabVIEWAdventure Thanks again for your reply. It's true that this task of conceptualization or abstraction can only be successfully carried out after multiple wrong decissions. So If think that I might have been a bit ambitious when suggesting to go directly the abstraction without facing firstly a specifc example. Anyway I will be happy to see the video you have in mind if finally is published. Of course, I know that maybe we are far away from that point as we all need to dedicate time to our jobs, family, friends and so on. So please, just keep on with this channel as far as your constraints allow you. I'm sure I'm not the only one that is enjoying it.
Hi Tom, thanks again for these series. I have one question though. At around 4:00 mark you show how to integrate the nested actor messaging system into private data of the Calling actor. However, the abstract actor itself also keeps tracks of the nested actor enqueuers, by invoking the Record Nested Actor.vi inside the Launch Nested Actor.vi, which does exactly the same thing. As a result, there is an array of the nested actor enqueuers in the abstract Actor private data (which is as far as I can tell only accessed by the abstract Stop Core.vi) and the same array in the child actor that you create in the project. Isn't that redundant? The duplication of the Enqueuers array in the child actor can serve as a workaround as it looks like you cannot normally access the abstract Actor nested Enqueuers array, but can it potentially lead to conflicts? Thanks.
Hi Dmitry - great question, When we launch an actor, the nested actor's enqueuer is stored by the calling actor and is only used by the "Auto-Stop?" functionality - So if the calling actor stops, it can stop all the nested actors. However, we (as developers) don't have access to that list as it forms part of the private data of the actor class. Instead, we keep our own register of nested actors so we can send the nested actors messages. I wouldn't call it a workaround as the two arrays of enqueuers are used for different things. 1 is used exclusively for the "Auto-Stop?" functionality; the other is for us to use to send messages. Regarding conflicts, the two arrays are completely separated by inheritance, so there's no chance of a mix-up. Hope this answers your question, Cheers, Tom
Thanks, Tom. I think that having the list of nested actors at the developer's disposal is also beneficial because the built-in termination sequence propagates the stop signal from the calling actor down to the chain, and the only case it happens in reverse is when an error occurs in the nested actor and it sends its own error up the chain, which will kill the entire application. In the most applications I was developing, the termination sequence is reverse, i.e., I am first sending termination signal to the top actor from the UI, but wait until the nested actors finish their work, terminate gracefully and send the confirmation of the normal exit up the call chain, only then the calling actor exits (and sends its own confirmation up its chain). I implemented it by overwriting Handle Error. vi of the nested actor(s) and included the abstract message to the caller which sends exit confirmation. By the time the calling actor receives this message all actors below it already exited (once the Actor Core loop reaches Handle Error, it no longer accepts messages). If a calling actor launches multiple nested actors, it waits until the nested actor callers array is empty, assuming each confirmation leads to removal of the calling enqueuer from the calling actor database. That database needs to be accessible to the developer.
Hey Tom! I've got an error when I clicked on 'Rescript Message'. Error was "Error 20 occurred at Message Rescripter.lvlib:Derive Target Method Name.vi ". Could you explain why I got this error.
Hi Tom, Really appreciate your efforts in to this video series. Question - After completing all the steps you explain in this video, imagine I need to replace the Update UI method in controller class with something else. I simply removed the method and deleted the file from the folder. Then created my new method, generated the method and replaced the old Send Message with the new one. Then I got errors when saving the project - obviously because the previous method "send Message" & "Do.vi" is scripted in other places and held in memory. Could you please explain the best way of replacing a method in a project (which has already scripted its message)?
Hi Asanka, I can't remember what I actually did in this video! However, it sounds like you're wanting to change the functionality of the method. You can do this either by opening the method and changing the block diagram (if you also change the connector pane, you'll have to right-click the message class in the project and Rescript Message. Another approach would be: instead of changing the functionality, you could make a child class of your actor and override the method you want changing. The second approach would mean you're never loosing "known and working code" instead you are appending to it. Does this answer your question?
Hey, it's been awhile since I looked at this, do you have a timestamp of when I did this, or was it a more general question? IMO, there is no reason to ever use a flat sequence structure, however, I might sometimes use a single frame sequence to ensure data flow if I don't want to pass the error through (if I want something to function regardless of if an error occurred)
Just a quick update. I think I got 'Flat' and 'Stacked' sequence structure mixed up. You should never use stacked sequence structures. However, flat sequence structures can be used occasionally to help implement error handling and data flow
That's there to simply give an extra layer of separation. It means we can swap out a user interface or business logic without effecting the other actors
3 Times after "Rescript Message" I got errors in "Actor Core" Methods of all Actors. And I couldn't fix them. Redone all the program from the very beginning till I got no errors I am afraid, if the same problem could be in a real project =/. Could you please show debugging tools in LV in next Videos? And THANK YOU FOR THIS WORK - IT IS THE BEST!
Hi Alexandr, sorry for the delay. I'm slowly getting through the comments! Whenever there's an error in a DD override VI (in this case Actor Core), LabVIEW often says there is an error in every override. Which isn't very helpful! However, in LabVIEW 2019+ whenever you open the Error List (Ctrl+L) it will comeup with a ROOTCAUSE item, if you doubleclick that, it should take you to the specific VI that needs fixing.
Do you remember how you added the DBL array into the interface and resulting messages after forgetting it? I created a message before adding it, and it won't let me rescript it, "this message does not target an actor's method. it cannot be rescripted".
@@TomsLabVIEWAdventure Ahhhh I realized now that the input of messages created in the interface do not need to be updated, as they will never receive an input as an (abstraction?). It seems to be satisfactory to rescript the message inside the inheritor(business logic) to receive the updated input, and to leave the interface message with out the updated input! (I also realized that you waited to create the messages until the interface vi already had the input so you didn't actually run into this problem!)
Hey Haitham, Select the invoke node, Ctrl + Space, type 'fp.open', Ctrl+Shift+B. That should work. I'm not sure which version of LV that was introduced in though
One million Kudos for the brilliant way of explaining complex concepts in a way easy to understand. That is an art only a few master.
Thanks!
I seriously cannot thank and praise you enough for this magnificent tutorial.
Great video Tom... You will probably get about 10 views from me just trying to wrap my head around the Actor Framework! But seriously, this series is one of the best I have seen on the subject. Thank you!
Thank you so much for these videos! I appreciate the planning and design of this series, it must've been quite the effort!
This is a great tutorial. Would love and so greatly appreciate if you could make more videos targeting data acquisition, measurement and testing, etc. examples (i.e. things LV was designed for). For instance, how can one incorporate file I/O, signal processing functionality, dynamic data visualization, etc.
Hello Tom! Firstly I wanted to thank you for the great contribution you are making with this TH-cam Channel. As LabVIEW developer, I really enjoy your videos.
I wanted to make you a kind suggestion. I think that a short video explaining how to pass the CLA Exam based on an AF approach would be really useful for everyone willing to obtain such certification. Indeed, I think that it could be a good example to show the AF capabilities and how it can be used for architecting real applications.
Hi Victor, thank you for the feedback :)
I'm not sure about creating a video specifically about passing the CLA because I want to teach developers how to AF properly as opposed to 'giving the answer' - but I'll look for further feedback to see if people would like an AF CLA 'master class'.
While we're at the point in the AF series where I'm still explaining the basics of design, overrides, and implementation I wanted to stick to a really simple example (chat room). However, once all the basics are out of the way, I was thinking about writing a fully functional CLA paper (Elevator sample paper) in AF which I would do a code review video on. How does that sound? Please keep the feedback coming.
Hi Tom! Thank your for your quick reply. Of course, I understand that as now you are introducing the AF basics it's a bit soon to consider a more complex case as a AF CLA. So, I agree with you that the best moment to think about it is once all the fundamentals have been introduced. From my point of view, what I think it's really useful is to understand how an application can be divided into separate modules (Actors in this context) and how those modules are related according to a tree-structured hierarchy.
So my idea is not about showing how to face a specific exam and where to place its covers but to show how (and why) a "Template AF Architecture" is designed in a way that makes it applicable not only for one specific case or exam but for a variety of them. In that case, it could be considered as a starting point, like a project template. In other words, I would say that the goal shouldn't be learning to solve one single exam but learning to think as a LabVIEW Architect using the AF. Please, let me know if you consider this approach interesting. Of course, I offer you my help if you think it could be useful in any way. Despite this, if you think it's better to focus on a specific case (like the Elevator exam AF-solution) and to do a code review video it will be great and really appreciated as well.
I will be happy to read your feedback.
It's an interesting one that's difficult to explain. For example, when learning about the humble state machine, it was difficult to know what constituted an individual state, then moving onto classes, knowing what classes should be made, and now with actor, you need to be able to define individual processes*. Once, the AF basics are out the way, I could take a CLA requirements specification and treat it like a customer's brief, then do an AF design video where I talk about my thought/design process.
It will probably be a couple of months before I have time to do that as I have courses to teach / presentations to write (CLA Summit in Krakow this year!) - as well as a full time job!
*Just remember with software design - Good judgement is only made from making lots of bad judgements! ;)
@@TomsLabVIEWAdventure Thanks again for your reply. It's true that this task of conceptualization or abstraction can only be successfully carried out after multiple wrong decissions. So If think that I might have been a bit ambitious when suggesting to go directly the abstraction without facing firstly a specifc example. Anyway I will be happy to see the video you have in mind if finally is published. Of course, I know that maybe we are far away from that point as we all need to dedicate time to our jobs, family, friends and so on.
So please, just keep on with this channel as far as your constraints allow you. I'm sure I'm not the only one that is enjoying it.
Hi Tom, thanks again for these series.
I have one question though. At around 4:00 mark you show how to integrate the nested actor messaging system into private data of the Calling actor. However, the abstract actor itself also keeps tracks of the nested actor enqueuers, by invoking the Record Nested Actor.vi inside the Launch Nested Actor.vi, which does exactly the same thing. As a result, there is an array of the nested actor enqueuers in the abstract Actor private data (which is as far as I can tell only accessed by the abstract Stop Core.vi) and the same array in the child actor that you create in the project. Isn't that redundant? The duplication of the Enqueuers array in the child actor can serve as a workaround as it looks like you cannot normally access the abstract Actor nested Enqueuers array, but can it potentially lead to conflicts? Thanks.
Hi Dmitry - great question,
When we launch an actor, the nested actor's enqueuer is stored by the calling actor and is only used by the "Auto-Stop?" functionality - So if the calling actor stops, it can stop all the nested actors. However, we (as developers) don't have access to that list as it forms part of the private data of the actor class.
Instead, we keep our own register of nested actors so we can send the nested actors messages.
I wouldn't call it a workaround as the two arrays of enqueuers are used for different things. 1 is used exclusively for the "Auto-Stop?" functionality; the other is for us to use to send messages.
Regarding conflicts, the two arrays are completely separated by inheritance, so there's no chance of a mix-up.
Hope this answers your question,
Cheers,
Tom
Thanks, Tom.
I think that having the list of nested actors at the developer's disposal is also beneficial because the built-in termination sequence propagates the stop signal from the calling actor down to the chain, and the only case it happens in reverse is when an error occurs in the nested actor and it sends its own error up the chain, which will kill the entire application. In the most applications I was developing, the termination sequence is reverse, i.e., I am first sending termination signal to the top actor from the UI, but wait until the nested actors finish their work, terminate gracefully and send the confirmation of the normal exit up the call chain, only then the calling actor exits (and sends its own confirmation up its chain). I implemented it by overwriting Handle Error. vi of the nested actor(s) and included the abstract message to the caller which sends exit confirmation. By the time the calling actor receives this message all actors below it already exited (once the Actor Core loop reaches Handle Error, it no longer accepts messages). If a calling actor launches multiple nested actors, it waits until the nested actor callers array is empty, assuming each confirmation leads to removal of the calling enqueuer from the calling actor database. That database needs to be accessible to the developer.
incredible work! many thanks!
Great Videos ! Thanks a lot :)
Hey Tom! I've got an error when I clicked on 'Rescript Message'. Error was "Error 20 occurred at Message Rescripter.lvlib:Derive Target Method Name.vi ". Could you explain why I got this error.
Nice, I watched a CLA practice test and the programmer used "model" quite a bit. Looking forward to an explanation of that lol
Hi Tom, Really appreciate your efforts in to this video series. Question - After completing all the steps you explain in this video, imagine I need to replace the Update UI method in controller class with something else. I simply removed the method and deleted the file from the folder. Then created my new method, generated the method and replaced the old Send Message with the new one. Then I got errors when saving the project - obviously because the previous method "send Message" & "Do.vi" is scripted in other places and held in memory.
Could you please explain the best way of replacing a method in a project (which has already scripted its message)?
Hi Asanka, I can't remember what I actually did in this video! However, it sounds like you're wanting to change the functionality of the method. You can do this either by opening the method and changing the block diagram (if you also change the connector pane, you'll have to right-click the message class in the project and Rescript Message. Another approach would be: instead of changing the functionality, you could make a child class of your actor and override the method you want changing. The second approach would mean you're never loosing "known and working code" instead you are appending to it.
Does this answer your question?
Hey Tom, is there a good reason to use the flat sequences instead of wiring the errors for sequence control?
Hey, it's been awhile since I looked at this, do you have a timestamp of when I did this, or was it a more general question?
IMO, there is no reason to ever use a flat sequence structure, however, I might sometimes use a single frame sequence to ensure data flow if I don't want to pass the error through (if I want something to function regardless of if an error occurred)
Just a quick update. I think I got 'Flat' and 'Stacked' sequence structure mixed up. You should never use stacked sequence structures. However, flat sequence structures can be used occasionally to help implement error handling and data flow
@@TomsLabVIEWAdventure You use it at around 8:10 in Actor Core. It makes sense then, if you don't want the error to get passed through!
Hi Tom. This is a great video series. Appreciate your efforts. My question here is what is use of model actor between the server and controller?
That's there to simply give an extra layer of separation. It means we can swap out a user interface or business logic without effecting the other actors
3 Times after "Rescript Message" I got errors in "Actor Core" Methods of all Actors. And I couldn't fix them. Redone all the program from the very beginning till I got no errors
I am afraid, if the same problem could be in a real project =/.
Could you please show debugging tools in LV in next Videos?
And THANK YOU FOR THIS WORK - IT IS THE BEST!
Hi Alexandr, sorry for the delay. I'm slowly getting through the comments!
Whenever there's an error in a DD override VI (in this case Actor Core), LabVIEW often says there is an error in every override. Which isn't very helpful! However, in LabVIEW 2019+ whenever you open the Error List (Ctrl+L) it will comeup with a ROOTCAUSE item, if you doubleclick that, it should take you to the specific VI that needs fixing.
Do you remember how you added the DBL array into the interface and resulting messages after forgetting it? I created a message before adding it, and it won't let me rescript it, "this message does not target an actor's method. it cannot be rescripted".
I'm pretty sure I just added the double to the connector pane and rescripted. If that doesn't work, you could add it manually to the send message VI
@@TomsLabVIEWAdventure Ahhhh I realized now that the input of messages created in the interface do not need to be updated, as they will never receive an input as an (abstraction?). It seems to be satisfactory to rescript the message inside the inheritor(business logic) to receive the updated input, and to leave the interface message with out the updated input!
(I also realized that you waited to create the messages until the interface vi already had the input so you didn't actually run into this problem!)
how you change invoke node by typing in quick drop [fp.open] it doesn`t work wit me in LabVIEW 2020
Hey Haitham,
Select the invoke node, Ctrl + Space, type 'fp.open', Ctrl+Shift+B. That should work. I'm not sure which version of LV that was introduced in though
Thank you for this
can you share some thoughts on optimized database handling?.. like "ActiveRecord".. i just saw video about it, but didn't found on vipm.