DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

How to enqueue initialisation steps without self-enqueuing

I want my module to undergo a sequence of uninterrupted initialisation steps. I understand that if I'm referring to a child module I can get the parent to send an array of messages to instruct this (would this be the way?)

But if I want my parent module to init across multiple steps, and so there's no calling code to send the instructions, I'm not clear on how to avoid self enqueuing.

 

Firstly, to start the init at all- I've seen that it's not recommended to put any specific init work into the initialise case, instead using a 'configure' case, but how do I trigger this configure case? I want to just enqueue it from the init case, but is there a better way? Shall I enqueue it in the modules startup code like the initialise is?

Then, I need more than one configure step, the first reads the various config files, the second sets up the hardware. Previously i would have self enqueued these, but is there a better way? Should the configure case include a state machine that goes through each of the steps I need? 


Separate question but loosely related, is it acceptable to put certain initialise code before the module? Like 'pre launch init' in the actor framework.

 

Sorry this is quite a lot, this is my first DQMH project and I'm trying to establish good habits for going forward 

-------------------
CLD
0 Kudos
Message 1 of 11
(319 Views)

To me, module declaration, initialization and configuration (regardless of framework used) mean the following:

Declaration: establishment of the identity of the module before it is launched. This is done by the calling routine (a launcher/main VI or a parent module) and fed to the 'Start Module' VI if necessary.

Initialization: synchronous execution of a sequence of steps triggered internally within a module upon its launch. If ALL of these steps run successfully, the module exists 'independently' and is able to communicate externally. If ANY of these steps fail, the module cannot exist.

Configuration: execution of a set of steps triggered internally or externally that set (or reset) the state of a module.

 

Configuration steps are done as part of initialization also, with initial values, to set the 'initial state' of a module. These steps could be re-run with different values per your application requirements.

 

That said, if your module has VIs like:
Init_Step_1.vi
Init_Step_2.vi

Init_Step_n.vi

Config_Step_1.vi

Config_Step_2.vi

Config_Step_x.vi

 

Your module's initialization case could have a single Initialize_Module.vi that internally invokes all the above as SubVIs in desired order. The outcome of this VI determines whether your 'Module Did Init' or not. Accordingly, you can define your 'configuration' request events per desired application logic to invoke one or more of these 'Config_Step_*' VIs.

 

That said,


@Shiv0921 wrote:

But if I want my parent module to init across multiple steps, and so there's no calling code to send the instructions, I'm not clear on how to avoid self enqueuing.

You may have a situation where one module's initialization success is dependent on one or more sub-module's successful initialization. In such a situation, you will need to trigger that module's 'Module Did Init' broadcast in the appropriate message handling case where it has determined successful startup of all its necessary sub-modules.

 

In this module design scenario, the sub-modules would be considered 'internal' to the launching (Parent) module. (In other words, the design would be implying that if any of these sub-modules could not initialize successfully, then the Parent module has failed initialization and can no longer exist. The Parent will shut down, and consequently shut down other sub-modules that are already initialized.

 


@Shiv0921 wrote:

Firstly, to start the init at all- I've seen that it's not recommended to put any specific init work into the initialise case, ... 


What does this mean? Where have you seen this? Can you provide a link or example? The statement, by itself, doesn't make sense to me.

 

Message 2 of 11
(291 Views)

@Dhakkan wrote:

@Shiv0921 wrote:

Firstly, to start the init at all- I've seen that it's not recommended to put any specific init work into the initialise case, ... 


What does this mean? Where have you seen this? Can you provide a link or example? The statement, by itself, doesn't make sense to me.


This might come from the HSE way of working. For us, the "Initialize" case of a DQMH module's MHL is a framework function. We make a point of not putting any business logic into it.

 

Every single one of our modules implements a "Configure" request which we trigger externally to tell the module to go find and load its configuration, and potentially also do more, depending on the nature of the module.

 

If the module needs to connect to hardware, a database, etc, we will implement a separate "Connect" request (ie that's neither part of the initialize nor of the configure case).




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® (Developer Experience that makes you smile )


Message 3 of 11
(275 Views)

 

@joerg.hampel wrote:


This might come from the HSE way of working. For us, the "Initialize" case of a DQMH module's MHL is a framework function. We make a point of not putting any business logic into it.

 

Every single one of our modules implements a "Configure" request which we trigger externally to tell the module to go find and load its configuration, and potentially also do more, depending on the nature of the module.

 

If the module needs to connect to hardware, a database, etc, we will implement a separate "Connect" request (ie that's neither part of the initialize nor of the configure case).


Found it... Start » Knowledge Base » 01 Better Practices » Coding Conventions » 11 DQMH


HSE's design philosophy seems to mirror what I've seen elsewhere about an object's constructor never failing, thus guaranteeing a successful launch. I see value in that, and even do so when my use case warrants it.

 

But, a blanket statement without due rationalization, to not add code to the MHL's Initialize case, seems a bit prescriptive.

 

A possible counter-example: A UI module shows/hides or enables/disables its various Front Panel elements and their values to a known default upon initialization. Done within the Initialize case, such a module will always have a known state regardless of how many times it is terminated and relaunched. Of course, one could configure it through the external trigger immediately upon launch. The optimal approach would be dependent on the context of the application.

Message 4 of 11
(254 Views)

Dhakkan, 

 

Thanks for defining how you distinguish between the different elements of preparing a module to run, I think referring back to these will help me better distinguish what to put where.

I had wondered whether using a sub vi per init step all in the same case was fair game, or whether it was me just hiding a case that involves a lot of code. Though I can see that it's a good way to ensure all the parts of intialisation execute unninterrupted. Would you do this for something as lengthy as read config files, send config data out, configure hardware(?) I was thinking that cases should be pretty atomic, and was concerned that this would effectively block the MHL, but perhaps it being blocked during initialisation is the whole point.

-------------------
CLD
0 Kudos
Message 5 of 11
(234 Views)

Joerg, 

 

Thank you for that link! I’d seen about not putting anything in the initialise case by reading this forum, but hadn’t come across the link- it’s so excellent! So much guidance in there! Thank you for that being a public resource, I don’t work in a software oriented company so often wish I had some clarity on a lot of these things, so this is awesome of you guys to making that available to the labview community.

 

As for triggering the configure case in the root/main parent module does this come from the launcher vi that started the module? So you call start module and then send the configure request? Not sure why this hadn't occurred to me as an option

 

Additionally I noticed this note in there "Be careful when adding code outside the MHL and EHL, especially adding code that needs to be executed before entering the “Initialise” case of the MHL. If that code takes too long to execute, the module initialisation will time out and throw error 403683 (“Module was unable to synchronise events”)" - I appreciate that being mentioned, I wasn’t sure why it was recommended not to put code outside the MHL&EHL, and had wanted to put my initialization here to mimic the actor framework pre-launch init as it's what I'd become accustomed to, but this is a good reason to do things differently. 

-------------------
CLD
Message 6 of 11
(232 Views)

@Dhakkan wrote:

[...] a blanket statement without due rationalization, to not add code to the MHL's Initialize case, seems a bit prescriptive.

 

[...] The optimal approach would be dependent on the context of the application.


Yes, I agree with you - it is prescriptive. I also agree that it depends.

 

The focus of our company and team here at HSE is working with engineers of varying levels of experience, and finding ways to help them make their sw developer lives easier.

 

I've had many conversations with expert users who know of other, maybe better ways to achieve something we prescribe in a specific way. Will an advanced user be able to ignore our suggestions and be successful? Most definitely. Will our guidelines help novice users and small teams not to paint themselves into corners? I like to think so. 

 

Many of our better practices and a large part of our way of working cater to the above scenario. They are the essence of many years of working in small, diverse teams. They work for us, and I stand by them. At the same time, I surely understand that they're not everybody's panacea.

 

PS: Thanks, Dhakkan, for sharing your experience and opinion here. I appreciate it.

PS2: I like how you describe the method of "an object's constructor never failing" - I might borrow that 😉




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® (Developer Experience that makes you smile )


Message 7 of 11
(199 Views)

@Shiv0921 wrote:

Thank you [...]


Thanks for the nice feedback! Makes my day 😍

 


@Shiv0921 wrote:

As for triggering the configure case in the root/main parent module does this come from the launcher vi that started the module? So you call start module and then send the configure request? Not sure why this hadn't occurred to me as an option


Yes, exactly. If you take a look at our (free and open-source) HSE Application Template, you'll see that the "startup.vi" not only starts modules configured in the config.ini file but also executes the "Configure" request for each one of them. Seeing as that is done automatically, it's not a bother but gives more control over when things happen.




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® (Developer Experience that makes you smile )


0 Kudos
Message 8 of 11
(194 Views)

@Shiv0921 wrote:

[...] defining how you distinguish between the different elements of preparing a module to run [..]


It's questions like yours that help crystallize my thought processes. 🙂

0 Kudos
Message 9 of 11
(127 Views)

Joerg,

 

My sincere apologies for making you go on the defensive.

 

I respect both - HSE's paradigm and HSE's choice to follow it - no questions there.

 

The point I should have made clearer was: the reader of your site would benefit from understanding why HSE chooses a no-code-initialization approach. The statement, all by itself, appears counter-intuitive to the notion of doing something to initialize.

 

In fact, I had started typing about a rationalization statement your site did provide to another point on the same page... One line states: 'Put all self-created VIs into /SubVIs/ folder [...]'. A rationalization immediate follows: 'Helps separate scripted/generated VIs from self-created ones'. I wanted to highlight the helpfulness of this second statement.

 

I honestly don't know why I deleted this initial thought, and instead put a counter-example... in hindsight, that example clearly caused a digression.

 


@joerg.hampel wrote:

[...] - I might borrow that 😉


If you do, don't attribute it to me 🙂 - I'd read about that a while ago and don't recall the source.

 

Edit: Fix tone of statement.

Message 10 of 11
(124 Views)