Jump to content

[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
Link to post
  • Replies 297
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Writing the notes forced me to watch the videos closely. I'm going to use the notes as a quick-ref whilst getting started and hoped others might have a go if they had them too. Feel free to make chang

For anyone using this package, I’ve uploaded the latest version (should really have updated this more than once a year).  I’d like comment on the following new features: This is one of three asynch

I am trying to shift discussion of Messenger Library to a group at NI, as this conversation is at 12 pages and is hard to follow. New post about a beta feature  for TCP that I am working on: http

Posted Images

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

Link to post

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
Link to post

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?

Link to post
  • 3 weeks later...

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

Link to post

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
Link to post

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

Link to post

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. 

Link to post
  • 1 month later...

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

Link to post

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.

Link to post

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

Link to post

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.

Link to post

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

 

Link to post
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
Link to post

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

Link to post
  • 4 weeks later...

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?

Link to post

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.

 

Link to post

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
Link to post

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?

Link to post

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
Link to post
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.

Link to post

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
Link to post

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.

  • Similar Content

    • By drjdpowell
      An extensive library for passing messages between parallel processes. Generalizes the communication method, allowing the message sender to use the method provided by the receiver. Supported communication methods include wrappings of simple queues, user events, and notifiers, as well a more complex channels such as a TCP server and client. In addition, one can configure simple forwarding addresses (“Observers"), which can send messages to multiple destinations, optionally with modifications such as adding a prefix to the message label, relabelling, or substituting a different message.
      Communication patterns supported include request-reply (asynchronous or synchronous), where the reply is sent to a "reply address" attached to the request, and register-notify, where one process sends a registration message to another in order to subscribe to a series of updates.  Also supports scatter-gather, the gathering of replies from multiple senders into an array of messages.
      An option framework for dynamically-launched VI "actors" is also provided, including example templates, which can be accessed via the Tools menu (from an open Project, select Tools>>Messenger Library>>Create Actor from Template..).  An "Actor Manager" debug tool is also installed under the Tools menu.  Please note that this package has nothing directly to do with the NI Actor Framework (other than both packages are influenced by the Actor Model).
      ***Introductory Videos are on a YouTube channel.***
      ***A great summary of many Messenger Library sources, provided by Bob W Edwards***
      JDP Science Tools group on NI.com.
      Original conversation on this work is here.

      Now hosted on the LabVIEW Tools Network (but note that the latest version will often be on LAVA)
      ***NOTE: latest versions require VIPM 2017 or later to install.***
    • By drjdpowell
      I've started to make some instructional videos on YouTube for my Messenger Library.   I was inspired by Delacor's nice videos on their new DQMH framework and also by Steve Watts' CSLUG channel.  Any feedback appreciated.
       
      James
    • By drjdpowell
      I’m hoping to add some sample projects to my “Messenging” package, and I thought it would be easy and instructive to rework one of NI’s templates, “Continuous Measurement and Logging”, as it is already somewhat actor-like with three communicating modules.  Attached is a (back-saved for 2011) copy of the NI project, with my version included (run “Main.vi” for the original, “Main.lvclass:Actor.vi” for my version). 
       
       I kept the basic functionality the same, but couldn’t resist changing some of the UI (in the old code, “Main” controls the UI; in the new code, published state messages from the Acquisition and Logging Actors set the UI).
       
      Continuous Measurment and Logging with Messenging.zip

       
       Any comments appreciated.   Is this example less clear than the NI original?  Why?  How could I improve it?
       
      In particular, is code like this (the most complicated interaction, I think) understandable without heavy documentation?  It’s a “Start Logger, then Start Acquisition, then Unset the Busy Cursor” three-actor chain message:

      I’m thinking of making a “Send Chain Message” subVI (that accepts arrays of addresses and message labels) to replace the above code.
       
      — James
    • By torekp
      At http://zone.ni.com/d...a/epd/p/id/4394, NI provides some example code for using Windows Messaging in Labview 2009. But the example generates and intercepts the messages in the same single toplevel VI. Is it possible to converse between two VIs using Windows Messaging? Would I need (or be able) to create a new DLL in order to do that?
      Toplevel:

      Create Windows Message Queue:

      From the Readme file:
      **How it works**
      A DLL included does all of the dirty work. The VIs in the library are primarily
      wrappers around the DLL with the exception of Wait for Windows Message.vi.
      When creating the first Windows message queue, the DLL installs a windows Get Message Hook and a CallMsgProc Hook on the LabVIEW process. This allows the DLL to inspect all messages heading for LabVIEW before LabVIEW processes them. The hook function determines whether each individual message is a message in which the queue is interested. If it is, it adds the message to the queue, and sets an occurrence. The Wait on Windows Message.vi is waiting on the same occurrence, and thus it continues its execution, retrieving the message from the queue. A number of utility functions are also provided for working with the queue.
      --------
      Any advice appreciated, even if it's "abandon all hope". (I'm a very weak C programmer.) I'm attaching the CPP code for the DLL, as a text file.
      Windows Messages for LabVIEW.txt
    • By jbjorlie
      I am working on a complete redesign of our instrument control software. I'll be using LVOOP and some form of messaging/queue system. The program must control 10+ different types of instruments, each having variations in I/O (pressure control, temp control, motors, different types of controllers, etc...). Most of our instruments run from a touchscreen attached to an embedded PC. A few run from a desktop and we have some that need the desktop version to control multiple instruments at the same time (using a tab control in my old program).
      So far I have a top-level vi that decides if this is a touchscreen, desktop, or simple test-viewer and launches the proper set of user interfaces. There are UI's for IDLE state, Test Setup, Config, Calibrate, Run Test, and so on... I have been studying discussions here from the super-megadudes on frameworks, lvoop, messaging, and how NOT to do things. After giving my best shot to AQ's AF I'm now using LapDog messaging from Daklu & it is time to ask some questions!
      1. Would you recommend using a single top-level UI and then plugging in different pages (Test Setup, Idle, Run Test, etc...) via sub-panels? In the past I have found that complex sup-panels can really slow things down. However, without them I end up seeing the desktop when switching between UI's. Not a big deal but not very professional looking.
      2. On the framework subject, is it better to have my I/O channels messaging a mediator who then messages the current UI or should they message the UI directly?
      3. What about updating indicators? It seems that passing UI indicator references to CHx is faster than CHx sending messages to the UI (or to mediator then to UI). I need good response time: Example - I want an LED to light up on the front panel when a heating relay is turned on and off. The relay may only be on for 50ms every second. Can I really send a LED ON msg and then an LED OFF msg and expect it to work smoothly? For 2-8 channels at once?
      3. Should I be re-opening the channels every time I switch UI pages or should I initialize them once and leave them running even when they are not doing anything? If the latter, what happens to the queues when the UI closes and another opens? I could pass the callee queue but what about the caller queue?
      4. I have a CHx parent class with children for each I/O "type". At runtime, some stored config information would tell CHx what child to use, which channel # this is, what to label the UI controls and indicators, and, according to the type of UI (also using classes), which controls to show/hide for appropriate functionality. There was a thought of giving each I/O class a UI and then plugging them into sub-panels on the bigger UI but I thought that may be too confusing for the poor sucker that inherits my code. It already seems that using LVOOP and a messaging framework distorts what I think of as "dataflow" drastically. Any quick thoughts on this or pointers to similar discussions?
      Here are some UI screenshots so you can get an idea of what I am doing:

      I truly attempted using the Actor Framework from the bottom up but I just cannot wrap my head around implementing it on this scale. Everything is so deeply encapsulated that I cannot figure out how to actually DO anything! LapDog allows me the freedom to implement a moderate amount of LVOOP without having to wrap every aspect of the program into classes and messages.
      I know that's a mess of vague questions for a single post, sorry! I'm new to all this.



×
×
  • Create New...

Important Information

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