We are finishing up the on paper design of an application for a test system. This will be our first application using DQMH. We have been studying it in detail, have watched most of the videos, and read many articles (Including the DQMH best practices article).
For this test application, we have broken the functionality into the following modules: AppMgr, UI, TestSequencer and Database. Our UI has no logic (simply requests to show things, and broadcasts when the user interacts with it). The Test Sequencer manages the execution of a list of tests and has a helper loop that executes the tests as state machines. The Database module simply retrieves settings and records data in a database. To promote responsiveness we are leaning towards using only requests and broadcasts instead of Request and Wait for Reply.
Our question is... how we should implement the state machine that we designed for managing the application? As currently designed, our AppMgr module needs to register for lots of broadcasts from each of the other modules. We have modeled the AppMgr with a state machine that contains 8+ states. The states do something upon entry and then perform various operations and sequences of operations when certain events are detected. There are currently 14 broadcast events from other modules that the AppMgr would need to register for. This is a relatively complex application.
Should this be implemented within a DQMH module? Our concern with using a DQMH module for the AppMgr is that although we can pass around a state enum through the MHL, the code seems like it might be harder to maintain since each message case would need to look at the state enum and any other state data to determine if the message should be handled and how to handle it. This seems like the same way state was managed in the NI QMH pattern. It seems like it would be easier to maintain the code if there was a case structure that had the state enum wired to the case selector, thus you could "see" everything related to a state within a single case. It also seems like we can't use Request and Wait for Reply events in the AppMgr if we are trying to put all of the business logic in the MHL instead of helper loops.
As an alternative to using a DQMH module for the AppMgr, we were thinking the state machine structure might look something like this (it would need to register for more than 1 module's broadcast events, but the images below should illustrate our thinking):
With that being said, is it better to simply use a DQMH module and check/change states within MHL message cases? Is our maintainability concern valid if we follow DQMH Best Practices?
You mentioned that you have done extensive reading, so before I go repeating something that you already checked out, have you checked any of the following?:
Thanks for your trust on DQMH,
Hi Fab and Joerg,
Thank you both for your suggestions. As we've looked into this more and evaluated the various approaches, it became more clear that there are several ways that we could implement our state machine. We decided to end up splitting up some of our states that had a lot of functionality into into separate states (e.g. Init became Init UI, Init Equipment, etc.). This seemed to address the maintainability concerns and removed some complexity because we could respond to broadcast events to know when certain operations were completed in order to transition states. We ultimately decided to use a DQMH module as the top-level VI for our Test Application. This Module is responsible for managing the application states and simply included a state enum on a shift register in the MHL. So far it's been very clean and easy to implement.
Once again, thank you for the suggestions and we look forward to developing our application with DQMH!