Jump to content
drjdpowell

[LVTN] Messenger Library

Recommended Posts

Hi James,

I tried your probe anyway - unfortunately it causes a deployment error (see image). Without investigating, I'm guessing there's something in there not compatible with RT?

I already log the 'states' to a log file, which is how I know if the appropriate states are being fired in each actor. Plus I log all errors to a separate log file.

Trying your ideas:
1) Already made that change, just in case
2) Double checked wiring - it's fine.

So I took a look at "vi.lib\drjdpowell\Messenging\ObserverRegister\ObsReg Core\ObsReg to Table.vi” which shows how to take an ObsReg Core class and represent it's data in tabular form. How can I use this to investigate the number of Observers on the subactor notifier before I send the reply? I presume this is the motive?

Deployment errors when using probes:

deployment_error.JPG

This is how I record the states to file:

log_state.JPG

Edited by Thoric

Share this post


Link to post
Share on other sites

OK, so I think I worked it out. I recover the DVR and run ObsReg to Table.vi and export to file. Unfortunately, introducing this diagnosis code caused the problem to vanish. With this code in place, the issue does not occur. Out of interest, the resultant table contains:

All State	ObserverSet; 
  0: EventMessenger (0x79B00000)	
All Events	ObserverSet; 
  0: EventMessenger (0x79B00000)	
All Errors	--	

We have one Event Observer established. Hence the message was received and no problem occurred.

For sanity I removed the diagnostic code and recompiled it, and the problem is still gone. Aargh! I haven't changed a single other thing! What's going on!?

review_observers.JPG

Share this post


Link to post
Share on other sites

And the problem has returned. No changes. This has to be a race condition. Sadly I no longer have the diagnostic code in there so I have no way to see if the Register had any Observers. I'll reintroduce the code and do some repeat testing (multiple reboots of CompactRIO).

Update:

I can no longer get it to fail. With or without the code segment above looking at the register, it now always works. And I've literally changed nothing else.

...I wonder if a career shift into crop farming would prove less stressful...

Edited by Thoric

Share this post


Link to post
Share on other sites

i don't think there can possibly be a race condition in the code itself.   If you send message A then B, then they are handled A then B.   Could there be a compiler bug on RT affecting either User Events or the DVR the ObsReg uses?

Share this post


Link to post
Share on other sites

i have a frame work that launches actors from and controller actor but with the latest version this ability is broken. after a lot of snooping i found the 'Get Dynamic Launch Shell Reference' was changed. I downgraded the messenger library to the previous version and everything is fine

 

dynamic launch new.png

dynamic launch old.png

Share this post


Link to post
Share on other sites

This is issue 9: 

https://bitbucket.org/drjdpowell/messenging/issues/9/non-reentrant-actors-started-by-themselves#

You can freely change the strictness of the reference to “Dynamic Launch Shell” if you like; so you don’t have to downgrade to an older Messenger Library version.

Edited by drjdpowell

Share this post


Link to post
Share on other sites

Hello James, I am not completely sure, if this crash really is related to the send.vi of your framework (version 1.9.6.99). Have you ever encountered such a LV crash? The crash occurs after a day of runtime (dev template based), where messages are frequently send to the same actor.

error.JPG

Share this post


Link to post
Share on other sites

I not aware of such an issue caused by Messenger Library, and that subVI does nothing other than fire a User Event.   Are you able to make an EXE and try that?

Share this post


Link to post
Share on other sites

Hello James, I tried to reproduce the error, but after a restart of the pc the error seems not to be occuring any more. Thanks for the answer and sorry for the beginner error not to test if restart would solve to problem. 

Share this post


Link to post
Share on other sites

Hi James,

I'm attempting to register two actors in my top level.vi. I've done this before in past projects, but for some reason following the same template I'm getting the following error:

Error 1 occurred at SendMSG.lvlib:Messenger.lvclass:Send.vi:2280001

Possible reason(s):

Attempt to send message to a virtual (non-valid) messenger.

Message label: "RegisterByLabel"

Not sure where to go from here... Any Ideas?

Error.png

Register.png

Share this post


Link to post
Share on other sites

That error is from when one tries to Send a message to the parent class of all Messengers.   The parent class is "virtual" meaning it is an error to actually try and use it, rather than a "concrete" child class like your EventMessenger (orange wire in the image).   Your Aerotech.lvclass "actor" has a Messenger inside it.   If you have never "Launched" it, then it will not contain a concrete child-class Messenger and will throw that error (note: it will throw a different error if it Launched and then Shutdown for some reason).

So, I think you have a bug somewhere upstream that has caused you to "drop" the address of your Aerotech actor, or to never launch it, and you are trying to send to a never-launched actor address.

I will try and improve that error message to mention unlaunched actors.

Share this post


Link to post
Share on other sites

James,

The Aerotech Actor is launched to a subpanel in the previous init steps, the actor is running in the subpanel. What sort of bug would cause the address to be dropped. How would I discover this bug, or better yet how would I go about fixing the problem? Should I re-write the Aerotech actor? Or do you think the problem may be in my Top Level Actor?

Thanks,

Bob

Share this post


Link to post
Share on other sites

My first suspicion would be you forgot to wire the newly-launched actor to your cluster (ie. you "dropped" or "lost" the address). The problem is almost certainly in your Top-Level actor.

Use Probes to debug your actor's address wire backwards.  Using the standard probe, an unlaunched actor address look like this (note the Messenger.lvclass):

Unlaunched Actor Probe.png

While a launched actor looks like this (note the EventMessenger substituted for Messenger.lvclass):

Launched Actor Probe.png

You can also use the custom "Address Probe", which looks like this:

Address Probe on invalid address.png

The "X" indicates an invalid address, though note that this could be a launched-then-shutdown actor address, rather than an unlaunched one.

Share this post


Link to post
Share on other sites

James,

You are absolutely right, I did drop the address. For some crazy reason I didn't think I needed to return the newly launched actors wire to the cluster... Costly mistake.

Thank you so much for your help.

Bob

Share this post


Link to post
Share on other sites

On various occasions I run into the problem where one of my Actors is broken and I didn't realize it (such as a Type Def needs updating, or maybe I accidentally left an Actor in an unfinished state, etc.).  This causes all Actors to not be able to be dynamically launched until the bad/broken Actor is fixed. Since the Actor is dynamically launched, I don't realize this until I try running the program.

 

Is there a good way to figure out which Actor is broken besides going through the process of opening all Actors to find out? 

 

Thanks,

Bruce

 

Share this post


Link to post
Share on other sites
13 hours ago, bmoyer said:

Is there a good way to figure out which Actor is broken besides going through the process of opening all Actors to find out? 

I use the ctrl-L shortcut key to bring up the Error List Window.  Broken actor will have a red X.

Broken Actor.png

  • Like 1

Share this post


Link to post
Share on other sites

Wow, so easy!  I guess when the top-level level VI isn't broken I forget that there's another way to bring up the error window beside clicking the broken arrow!

 

Thanks for all of your help!

Bruce

Share this post


Link to post
Share on other sites

Hi James, I was looking through the VIs and tried searching for an answer, but I can't seem to get my head around how nested actors get triggered to shutdown when their calling actor shuts down. I saw somewhere mention of a queue references whose sole purpose was to indicate to the nested actor if the calling actor is alive, but I cannot figure out how that is implemented in the code. I understand such info is not necessary for usage of the library, but I am curious. Could you please highlight the implementation of this feature?

Share this post


Link to post
Share on other sites

It's an asynchronous action called "Reference Monitor", a variant of the "Address Watchdog" available on the library pallets.   It's started inside "Startup type 2.vi".   That VI exchanges messages with "Startup Handshaking.vi" (inside "Launch Actor") in order to get a Queue created in the Caller for the Reference Monitor to monitor.   The Monitor is configured to send a shutdown message if the Queue dies.

 

Startup type 2.vi Block Diagram.png

 

BTW, this is one of the best examples of "internal complexity to support external simplicity" in Messenger Library.  Having things created by a Caller automatically clean themselves up is a major simplification, but to get this requires sophisticated internal plumbing.

 

Share this post


Link to post
Share on other sites

Holy crap you weren't kidding! That is one deep rabbit hole. I'm amazed at the internal complexity of this library. I guess you really did earn that Dr. title! Very clever solution with the asnyc call to spin-up the reference checker. Is there any reason for choosing a queue vs some other type of reference?

Edited by Conner P.
add a few words

Share this post


Link to post
Share on other sites

I needed a reference I can wait on, and I do not know of a lower-overhead option than a queue.

Share this post


Link to post
Share on other sites

Hi James, how would you recommend making a message class for a specific data type? As a little preview I am trying to make a thread pool class which includes a manager actor and worker actor clones. Normally I would find the variant solution satisfactory, but as we discussed in my post on the NI forum, I have a high throughput application and don't want to give up speed I don't have to.

My initial thought was to just make a subclass of MSG.lvclass like variantMSG.lvclass (sorry if the names aren't 100%, don't have LV with me atm), but then I discovered that the internal send and extract variant message methods DO have "abstract" parent versions within MSG.lvclass. I didn't want to go fussing with the library base classes, so instead I designed the send and extract methods of my customMSG.lvclass to accept a generic MSG object and then internally cast it to my custom child class, allowing the internal methods to do the extracting or writing.

Is this a reasonable approach?

Share this post


Link to post
Share on other sites

I, personally, rare!y make custom message subclasses, though it is my intention that one can use Messenger Library that way.  Somewhere on LAVA is an example I made of doing AF-style Command-Pattern messages.  But I generally either use variants or I create non-message object classes that I pass in messages (example: a dataset object, or job object, or fast-growing object).  The later have useful lifetimes longer than one message pass.

I'm not sure variants are that slow, btw, so I would benchmark before avoiding them.

Edit> "fast-growing object" is some strange auto-spell correction, but I can't for the life of me tell what I was meaning to write!

Edited by drjdpowell
Weird autospell correction

Share this post


Link to post
Share on other sites
7 hours ago, drjdpowell said:

I, personally, rare!y make custom message subclasses, though it is my intention that one can use Messenger Library that way.  Somewhere on LAVA is an example I made of doing AF-style Command-Pattern messages.  But I generally either use variants or I create non-message object classes that I pass in messages (example: a dataset object, or job object, or fast-growing object).  The later have useful lifetimes longer than one message pass.

I'm not sure variants are that slow, btw, so I would benchmark before avoiding them.

Ah yea, I hadn't considered using an object. But since I was planning on passing a cluster, what difference does it make if it is an object or a plain cluster? Not much in the message passing regard.

But, packing the data in an object does open the door to created class methods to manipulate the data, which in turn could use the command-pattern for the ThreadPool. With that, it wouldn't be so much passing in a set of parameters and returning a separate result, but more passing the object through the ThreadPool and "pushing a button on it"-- very assembly line like in my mind.

I think I just realized the potential of the command pattern.

Share this post


Link to post
Share on other sites

I use an object only when I'm doing a lot more than just passing data in a single message.  So a "job" object might be sent to the "Worker" actor, who calls "do job", but then the completed "job" is passed on to another actor who calls methods to reads the results.   Or a "data" object might pass through several actors for processing and display.   If I just want to pass a loose collection of data from one actor to another then I just use a cluster.  But I find it rare to do this, and my messages tend to either be a single piece of data (or array) or a tight collection of data that makes sense to be an object.

Edited by drjdpowell

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.