From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

JKI State Machine Objects

cancel
Showing results for 
Search instead for 
Did you mean: 

SMO Dependencies II (aggregation vs. composition)

Hi all!

I have been recenty submerging into SMO stuff and I fing it a bit unclear of how dependencies are managed in SMO.

I attempt to design a system where a partucular module (SMO) has several "by composition" dependencies which I easily can create and maintain with framework functionality. either by setting them up as static dependencies in "enumerate static dependencies.vi" or as dynamic dependency launch. As it is by composition relation, I am completely satisfied of register mainaining lifetime of those dependencies.

However, I want this module (module A) to to contain as well a module coupled  by aggregation (module B). I.e. I want module A to have access to reference and functions of module B, but do not shut it down at the end of module A lifetime.

I have a suspicion, that "shared resource" is a keyword in here, but unfortunatyely I have failed to figure out it's functionality.

Could someone help me with understanding how this part of SMO engine works?

0 Kudos
Message 1 of 6
(10,817 Views)

Hello Mike,

Shared Dependencies are not quite how to achieve this, although it is a related topic. The shared resource flag is simply to allow SMOs to browse for an already existing subsystem without being specifically referred to that subsystem by a caller. Think of a logger module that you want started once (by the top-level app) and you don't want to have to wire its reference to all the subsequent subsystems you spawn... now, each subsystem could check on start-up that a logger exist (with a certain name) and if it doesn't, then it spawns it.

When you use the Launch Dependencies primitive, your caller SMO automatically takes ownership IF no other SMO has already claimed ownership of the SMO dependency (Composition). If the dependency has an owner, it will aggregate instead.

In the specific use case you are mentioning, you would have two ways to have A aggregate B while not being responsible for its lifetime:

1- Inject "B" with an accessor, after "A" has been created (not using the Launch Dependency method). Your top-level VI is then responsible for the lifetime of B.

2- Create a "Top-level SMO" that creates both "A" and "B" as dependencies (either static or dynamic), then inject "B" into "A" using the "Launch Dependency" method. I would do that in the TopLevel's onStarted( ) override. Upon termination, "A" will fail to stop "B" because it is not the owner of its lifetime (no errors are generated, just a warning that will be ignored in the onStop( ) of your A object. The top-level SMO doesn't even have to be a specific class... you can use the SMO base as a container, just like in the example below:

This is what it would look like:

2016-08-15_11-06-18.png

* Please note that I found a bug in this implementation and it will be fixed in version 1.1.8+. Essentially, since A depends on B and B will be stopped before A (reverse-order than creation), there is a wrongly handled error 1556 that occurs during the top-level Stop( ) call because B has been destroyed and A expects to check if it owns it. This bug affects versions <=1.1.7.  You can still use this example, but until 1.1.8, you will need to start B before you start A...

Francois

GCentral ChampionCLA
0 Kudos
Message 2 of 6
(10,555 Views)

Thank you a lot! Your explanation has cleared out few things.

However, in your example it seems that you intend to stop B (and handle stopping error) rather than A (what I understood from your description).

Also, in your example you destroy only top-level SMO. Why it is not called also after stopping B? Is it intended to be called only once in application?

0 Kudos
Message 3 of 6
(10,555 Views)

When a SMO owns a dependency, it will automatically stop and destroy its reference. So you don't have to explicitly stop and destroy them in that example.

Stopping "B", in this diagram, is simply to show that the command will be ignored because only the Top-Level (owner) can do that operation. You can try stopping A as well, and it will ignore it too. If you drill into the Stop command, you end up running onStop( ), which loops on all dependencies to stop/destroy only those that it owns. To do so, it uses a shared key that is created on taking ownership. Only the caller can compute this key on the fly by using its private key. This ensures you cannot stop the dependencies of another SMO.

GCentral ChampionCLA
0 Kudos
Message 4 of 6
(10,555 Views)

That's also good piece of information.

So to clarify - the stop vi in flat sequence will not alter operation of any SMO? Just throw error and all: A, B and top level are still running?

0 Kudos
Message 5 of 6
(10,555 Views)

This is accurate.

GCentral ChampionCLA
Message 6 of 6
(10,555 Views)