Jump to content

drjdpowell

Members
  • Posts

    1,969
  • Joined

  • Last visited

  • Days Won

    172

Posts posted by drjdpowell

  1. The lifetime of references like Queues are tied to their calling “hierarchy†(basically the top level VI).   Your main thread creates the Queues, so they die with it.   Your other ‘threads’, started by ACBR, are actually independent hierarchies.   If your main thread finishes before they have a chance to read the final message, then that message is lost.

     

    Normally, I have the receiver of a Queue be the one to create it (and thus own it).  Use a temporary Queue to pass the created Queue back to the caller.

  2. I can't access the google+ or youtube page. Could you upload the slides here or just describe the race condition problem? I think we're talking about similar sets of issues but I don't see them as being all that horrible, so I'm curious why you're so against the idea. I tend to think it just ends up being a lot more work than it needs to be to make good code.

    I gave a talk at the recent CLD Summit in the UK where I explain the issue.  It is a public video on the CSLUG youtube channel.

    • Like 1
  3. I agree with smithd in that we always use more than one communication method. We often have multiple network streams and shared variables at the very least. Beyond that, we sometime implement other forms of messaging but unless your system is fairly slow (to rely only on SV), I would expect you'll need at least 2 methods and multiple "instances" of each.

    I haven’t had an RT project in several years, but if I had a new one I would probably stick to only a single (message-based) method of communication between RT and HMI, and possible only one instance of that.  What do other people who do a lot of RT work do?

  4. You have to be especially careful with this concept if you tend to Start/Stop VIs while your application is running or at shutdown time to stop your VIs in the right order.

     

    An advantage of many-to-one messaging is that, if you make the message receiver (the “oneâ€) the owner of the reference, then you don’t have to worry about reference lifetime at all.

    About messaging, we also use that method but I find that being able to call the object's method directly makes it a lot easier to handle sequential commands and error handling that may be happen during the method's execution.

    The secret there is the ability to wait on the reply to a message, and have any error passed back with the reply.  With synchronous methods to send a message and wait for a reply one can interact with an asynchronous loop just as if it were an object.

  5. Another option, that I don’t think anyone has mentioned, is using a by-val object, but placing it in a DVR (rather than the DVR in the object.   Then one can use the by-val object directly in one loop, or share it with a DVR among multiple loops.   And you have the ability to call multiple methods on the object within a single IPE structure, which can protect you against race conditions.

  6.  How big does the message data have to get before it starts significantly impacting performance?

    Messaging doesn’t actually cost anything (it’s just a pointer under the hood); it’s copying that can be expensive.   If you pipeline, with A collecting data to pass to B (without A keeping a copy itself), then there isn’t any copying.  Similarly, if you share data between loops with a DVR, but make a copy somewhere (to update an indicator, say), then you have the same overhead as if you had made a copy to send in a message.

  7. I note that the SQL code to do arbitrary planer cuts through a 3D cube seems relatively straightforward, with a single large table and a simple WHERE statement ("SELECT … WHERE ABS(1.2*X+0.3*Y+.9Z) < tolerance", for example).   So you should prototype that with a large dataset and see if the performance is sufficient.  Also, don’t neglect the 3D picture control for visualization.

  8. Which LabVIEW version? According to my own tests some time ago, there was no way to get lvlib, lvclass or similar >= LabVIEW 8.x files into an LLB.

     

    I think they mean creating Destinations set to LLB on the Destinations tab of the EXE build spec.  I tried putting LVLIBs in these Destinations and it seems to work.  

     

    Added later>> shoneil posted while I was experimenting.

  9. Notes on the 1.6 version:

     

    1) there is a “Create Actor From Template†option under the Tool>>Messenger Library menu.

    post-18176-0-83751300-1440274982.png

    the DEV template is what I mostly use, though there is also a JKI “Statemachine" version.

     

    2) One can now make actors non-reentrant.   To do this one must rename the “Actor.vi†to “ActorNR.vi†in addition to making it non-reentrant. 

    • Like 1
  10. One is a framework intended to be developed and modified, the other is a more or less closed module that the user is never intended to open, just use it.  One is feature complete, the other is a shell of an application. 

     

    Well, the internals of the framework are not intended to be modified (or at least that would be a very advanced use).  Application-specific code is meant to just be simple message-handling loops, with an API for passing messages.  No LVOOP beyond copying a template class containing one “actor.vi†method.  That those “actor.viâ€s are forced to be shared reentrant, with a resulting learning curve, is a problem.  This conversation has lead me to reattempt a way to allow non-reentrant actors and I think I have a solution that works well, with the ability for a CLAD to more easily find his way through the code.  I’m going to try it out in my current projects.

  11.  You can't easily just open an XNode. 

    Exactly.  They seem to me to be much harder for a CLAD to get to grips with than my async-called, shared-reentrant actors (though I am an XNode novice).   

     

     

    Yeah that's part of the problem, the only "standard" on making an actor design at the moment is the NI Actor Framework.  

     

    Poor wording on my part.  I don’t mean community standardization;  I mean developer or team standardization on using a limited set of ways of doing things, so that one be expert in those techniques, and one can read and understand code quicker.  I use my actors extensively, at multiple levels in my code.  I don’t use techniques like “Action Engines†or any asynchronous calls of custom VIs, because I’m standardizing on Messenger Library actors.

     

    The actor I did just today is a small, one-VI-API “helper†that adds functionality to a WaveformGraph.  It is based on the exact same actor template that is used by my “Top Level†main application, and is using the same standard techniques.  

  12. Just open the VI and see.

    Is that how your CLAD programmer learns about your Xnodes?   :)

     

    But your right, it is a problem.  Even though I could show someone what to do in minutes, it’s easy to have no idea what the first step to do is.  Fabiola is fighting that problem by providing several instructional videos for her new Delacor framework.

     

    I’ve been trying to develop a way to make my actors easily switched between reentrant and non-reentrant, so I can leave single-instance actors as more “just open and seeâ€.  It hard, because I don’t want to give up other simplifying features, like auto-shutdown of actors.

     

     

    The benefit in my mind was simple code. 

     

    As Fab points out, one can also provide a junior developer simplicity via a simple API or set of tools that encapsulates complexity.  And personally, I think there is simplicity in standardization, since there is so much effort in learning code structure.

    • Like 1
  13. The “Popout Window†actor was a bad example; there are multiple ways to handle UI windows.   I meant a more generic “thing running in parallel that receives messagesâ€.  The same app with the popout windows has a reconfigurable-on-the-fly chain of analysis actors that pass data messages between them.  Actors are selectable from a list of plugins, and actors must be started and stopped as the User makes changes. 

     

    Another example is a “TCP Connection†actor that is created for each connection made to a "TCP Listener†actor.

     

    One can, of course, make custom code for each case, with an asynchronous call and the setup of some kind of communication, but using a well-tested “actor†template gets one up and running quicker and with perhaps fewer bugs.


    The benefits of this type of design is the only thing that is asynchronous (and more difficult to debug) is the actual UI, not the actor it self handling all the messages.  Probing and opening that actor was easy because it was on the block diagram of my main running VI and I could hold CTRL and double click to open the BD.

     

    I don’t really understand these benefits.  The major point of “actors†is to make async easier to debug, so why do I not want the actual UI to be an actor?  Every time I’ve tried making a custom async thing I’ve regretted not using my actor template.   And I’ve never found opening and probing async actors difficult (they have a “Show Front Panel†message)**.

     

    — James

    **Haven’t worked with actors on RealTime, so it might be different in that case.


    You mean like the MDI Toolkit? That just uses a list and adding it to the list instantiates the window. Or is it something different?

    No, they are just simple actors with a subpanel to hold a front panel.  They allow adding behavior like adding custom right-click menu options, highlighting the window when the User hovered over an icon the represents the window in the main app, notifying a managing actor when the User closes the window, etc.  All this could be done with dynamic event registration in a central component, which is why it is a poor example.

  14. All this needs is the ability to specify terminal allowed types, including matching output types to inputs.   For example: “A must be a string", "B must be a numeric", “output C must be the same type as input Dâ€, etc.  Then it would be extremely useful (and would implement my long-declined idea).

  15. I tried version 3.8.11.1 and it all seemed to work OK, but I just want to make sure I'm not doing anything wrong.

    That’s fine.  I include the latest dll at time of package release for convenience, but you should be able to use any version.

     

    Also when building an installer using your SQLite Library where does the sqlite3.dll get installed - in the root directory of the executable?

    When building the EXE it goes in the “data†directory of the executable, and the “Open†vi looks for it there.   This should happen automatically, but if not you can mark it as “Always Include†in the EXE builder.

  16. On mobile so quoting fails me. I never have an actor be killed unless they all did. But if I want an actor to restart I send a message to it telling it to restart and it is in a state machine so it just goes to the data cleanup case then the macro initialize.

    Have you never had the use case of an arbitrary number of actors?  â€œRestart†works if you want 0 or 1, but what about N, specified at run time?  I made a “Popout window†UI actor just today to support an arbitrary number of independent windows in an application.  The actors start as needed and shut down whenever the windows are closed.

  17. Since your API provides access to SQLite from LV, as Rolf said, you have to change LV's understanding of time to match SQLite's. This allows any other APIs/apps to retrieve time from the db under the common (SQLite) definition so they can convert it to their own definitions.

    Would that help you?   They use Integers to store UNIX time, which has no partial seconds.   I can certainly add a Bind Timestamp (Integer) and make Get Column as Timestamp accept integers.  

     

    But how common is Julian days since 4714 BC?   Not sure if that should override LabVIEW’s definition of a DBL timestamp, especially as this would be a breaking change in the library.

×
×
  • Create New...

Important Information

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