08-12-2022 02:19 AM
Just to point out that Event Registration can accept arrays of User Events, so if a thousand modules all need to send errors to one place, that is one registration of an array, not a thousand-high Register for Events.
08-12-2022 07:36 AM
@joerg.hampel wrote:
@Ozfarmboy wrote:
The other thing BCousins is to be mindful of having too many dqmh modules.
I think everyone has a different view on this, but at WiS we've found that constraining the number of modules is a good thing. We don't have a hard limit. We just don't turn every single function into a module.
Noooo...
Ok, and now with less dogma 🙂 I find it interesting to read this. In my experience, I've never thought "if only I had not created this module", whereas I've found myself a number of times trying to be clever by avoiding a module, only to end up recreating most of the framework functions and eventually creating a module after all.
The nature of your application (or rather your system) will already dictate a certain number of modules which represent the physical world. On top of that, modelling the application will show how certain functions should operate independently or be built to be reusable. A DQMH module is a quite natural way to cater to this. This is also what I communicate to our customers in trainings or consulting engagements.
I'd really like to hear some more tangible reasoning so I can reflect on my position on this. Chris can you share more about how many modules made your life harder? How do others think about this?
I have definitely seen some projects where there were DQMH modules where every message was a request and wait for reply. In that case, why go to the trouble of making a DQMH module? It obviously doesn't need to be asynchronous. Why go to all that trouble? Why not just a class?
08-12-2022 07:42 AM
@drjdpowell wrote:
Just to point out that Event Registration can accept arrays of User Events, so if a thousand modules all need to send errors to one place, that is one registration of an array, not a thousand-high Register for Events.
I think I knew that but had forgotten. That is definitely a nice trick!
08-12-2022 09:59 PM - edited 08-12-2022 10:03 PM
I've gone away and considered my comments Joerg! Here are my internal guidelines on this matter, some of which have been freshly influenced by this conversation. I've re-written this text 2 times! Apologies if we're going a bit off topic of the original post!
1) Consider a helper loop first before creating another DQMH module.
a) Good examples of this is when you need unblocked cyclic code (ie state machine, or continuous data acquisition) - In my opinion it's better to be in a helper loop rather than having another module doing this and the MHL being a self-enqueuer. Having said that, if you're needing more than one helper loop in a module, that's when I would start to look at whether another module is the right choice.
2) Create a DQMH module if the code needs to be dynamic, self-managed, asynchronous, dependent on classes and is likely to be called in multiple places, or has a UI element. If it's not any of these things, does it need to be a DQMH module, and can a set of one or more wrapper VIs suffice (ie. a single VI, a library or a class - as per what Sam suggested earlier)?
a) If you're showing a dialog that has no need to be asynchronous, does it need to be a DQMH module? Can't it just be a Sub-VI?
b) Working with a fellow DQMH Trusted Advisor recently, he had made a nice single VI that performed a complex zipping up of a bunch of setup files. In this instance, even I was leading towards making another DQMH module. He said "Nah, it's just one VI"!
3) Consider when one module might be better than two. ie. If two different instruments/devices need to be tightly coupled or synchronised for a very specific use case.
a) I had a vision project. The image acquisition and triggering (via an FPGA) needed to be tightly coupled. Initially I had created a module for both camera and FPGA. In the end, I succincted it down into one module so that the Camera/FPGA could be acted on with more immediacy. It just made far more sense to me to be working with the direct APIs side by side, rather than going through DQMH module APIs.
b) Similar to above, we needed to have an XNET device tightly coupled / synchronised with NI DAQmx. Rather than creating a module for each, we made one module to achieve the synchronisation required.
Note that the above examples are the exceptions, and not the normal WiS approach.
4) Ensure you put some time into designing your application up front. As per Sam's suggestion, pay attention to hierarchy, and working out which modules need to know about other modules. By applying the hierarchy approach, you can apply encapsulation, and hence removing the need to have one module at the top that registers for broadcasts of every module in the application. Use Antidoc to show the actual hierarchy, to confirm if the modules are not too tightly coupled.
Just a note on hierarchy. My belief here is that typically you shouldn't need too many layers. We rarely have more than 3. If you've got 5 layers or more, I'd like to know why. What sort of application requires that many layers?
Would love to hear where this is a practical choice.
Example situations of where a hierarchy is of value:
a) You have a module that depends on a number of sub-modules. For instance, you have a UI module, that depends on multiple UI sub-modules (ie these could be dialog modules, or customised graphs or tables where you want to abstract away the graph manipulation code - ie lots of property node usage - kind of like a DQMH version of an Xcontrol), and those sub-modules are very specific to that UI module, and are not required anywhere else in the application. In this case, these sub-modules should be launched by the UI module alone, and the UI module should be the only module that receives the broadcasts from those sub modules, and the UI module should be responsible for shutting down the sub modules. In this case, the parent or top level module of the application does not need to even know that those sub-modules exist, and does not need to register for those module broadcasts or launch them upon starting. This in line with Sam's earlier comments, and his Dos and Don'ts about structuring your application.
b) Another example of the above is if you have a number of instrument/device modules that needs to synchronise or be brought together, you might then have a device manager module to organise these. We have done this in the past, but then cheated and passed the errors/status broadcasts all the way up to the top directly, bypassing the device manager. Now that I've thought this through, it wouldn't be too much effort to have those device modules only report to the device manager module and have the device manager module pass up any broadcasts (ie. error/status) as required. And as above, the device manager module is the only module responsible for launching, registering for broadcasts, and shutting down modules. With this in mind, does the parent/top level module need to know about all of the instrument modules? Perhaps not.
08-12-2022 10:48 PM
@Ozfarmboy wrote:
Just a note on hierarchy. My belief here is that typically you shouldn't need too many layers. We rarely have more than 3. If you've got 5 layers or more, I'd like to know why. What sort of application requires that many layers?
Would love to hear where this is a practical choice.
Agreed. 3 seems about the right for all but the largest projects. 1 layer for hardware, 1 intermediate control/coordination layer and the "root" to use AF terminology.
08-13-2022 03:03 AM
Arguably, in a hierarchical architecture the effective number of layers is always at most 3, as to any specific actor/module the only known layers are itself, the higher layer calling it, and the lower layer it calls.
08-14-2022 06:50 AM
@drjdpowell wrote:
Just to point out that Event Registration can accept arrays of User Events, so if a thousand modules all need to send errors to one place, that is one registration of an array, not a thousand-high Register for Events.
Good hint. That's how we register dynamically for modules' default broadcasts in our HSE Framework.
DSH Pragmatic Software Development Workshops (Fab, Steve, Brian and me)
Release Automation Tools for LabVIEW (CI/CD integration with LabVIEW)
HSE Discord Server (Discuss our free and commercial tools and services)
DQMH® (The Future of Team-Based LabVIEW Development)
08-14-2022 06:56 AM
@Ozfarmboy wrote:
I've gone away and considered my comments Joerg! Here are my internal guidelines on this matter, some of which have been freshly influenced by this conversation. I've re-written this text 2 times! Apologies if we're going a bit off topic of the original post!
Fantastic write-up, Chris. I agree with everything you say. All your guidelines help with designing modular applications. Kudos!
I didn't mean to say "create as many DQMH modules as possible", which would be equally as bad advice as "don't create too many modules" anymore (which I still find to be bad advice - sorry!). How many modules are too few or too many anyhow? What I meant to say is "create modules where a module is appropriate, don't try to create as many or as few modules as possible".
DSH Pragmatic Software Development Workshops (Fab, Steve, Brian and me)
Release Automation Tools for LabVIEW (CI/CD integration with LabVIEW)
HSE Discord Server (Discuss our free and commercial tools and services)
DQMH® (The Future of Team-Based LabVIEW Development)
08-14-2022 06:05 PM
Thanks Jeorg.
Agreed now that "don't create too many modules" is not the right attitude.
More importantly, plan out your project and the modules beforehand.