-
Posts
1,973 -
Joined
-
Last visited
-
Days Won
178
Content Type
Profiles
Forums
Downloads
Gallery
Everything posted by drjdpowell
-
Actor-Queue Relationship in the Actor Framework
drjdpowell replied to mje's topic in Object-Oriented Programming
mje was talking about using a “zero or calculated timeout”, a technique I’ve also used. If a zero timeout never executes your actor’s gonna fail anyway. -
Actor-Queue Relationship in the Actor Framework
drjdpowell replied to mje's topic in Object-Oriented Programming
I was thinking more of the use of a message queue as a job queue for the actor, rather than what to do about filtering messages, but the general idea would be to have the actor’s message handler serve as supervisor or manager of a specialized process loop. The manager can do any filtering of messages, if needed, or it can manage an internal job queue. It can also handle aborting the specialized process by in-built means that can be more immediate than a priority message at the front of the queue (like an “abort” notifier, or directly engaging a physical safety device). It wouldn’t be a hollow shell. -
Actor-Queue Relationship in the Actor Framework
drjdpowell replied to mje's topic in Object-Oriented Programming
I particularly second this. Actors should endeavor to read their mail promptly, and the message queue should not double as a job queue. -
Self-addressed stamped envelopes
drjdpowell replied to drjdpowell's topic in Application Design & Architecture
Hi Ben, The launch technique is stolen from mje’s “message pump” package. It’s used by the Actor Framework, also. The Actor Manager installs in a different location, and should be available under the Tools menu: Please note that the Actor Manager is badly in need of rewriting. It’s not pretty. What’s your use case for TCP? I have TCP Messengers in the package (which use TCP actors to run the client/server) that are intended to seamlessly substitute for other messengers (handling replies and observer registrations). At some point I will write the code to launch an actor sitting behind one of these servers. Do you want a TCP actor to talk to external non-LabVIEW code? BTW, I’m in the midst of writing a talk on this package that I’m going to present at the European CLA Summit. Of course, this has made me relook at lots of things I did and want to change them . I’m going to upload a new version before that summit in April. — James -
Actor-Queue Relationship in the Actor Framework
drjdpowell replied to mje's topic in Object-Oriented Programming
In the framework I’ve developed, I get a lot of use out of subclassing the central enqueuer-like class (called, perhaps too simply, “Send”). Below is the class hierarchy. But “assertions of correctness”, what’s that? Breaking down some walls will certainly lose something to what AQ is trying to do. Personally, I think the tradeoff in flexibility would be worth it, but it would mean that that flexibility would be used to build some problematic code. -
Actor-Queue Relationship in the Actor Framework
drjdpowell replied to mje's topic in Object-Oriented Programming
A related conversation I started was “Suggestion: A different class structure for Queues”. -
But aren’t you in danger of being the overzealous designer, Jack. You want to impose “Must Implement” of a “Construct.vi” on “Message”, a class that I don’t believe even has a constructor at the moment. And at least initially, you imagined this required constructor to be “Send”. What requirements could you have made at that point that were not, in hindsight, either blindingly obvious (“we need to construct our objects”), or overzealous (“must be called Send or Constructor”, "must have an Enqueuer input”)? You can’t enforce “must actually use this function”, so any error in requirements will just lead to unused “husk” methods made only to satisfy the requirements. — James BTW: There is an example of this very thing in the Alpha/Beta Task example in 2012, where “Alpha Task Message” has two independent constructors: a “Send Alpha Task”, following the standard pattern (not enforced, of course), and then a “Write Data” constructor written when it became necessary to write a message without sending it.
-
A good example, because “Send” being a method of Message has always looked wrong to me. Messages are written; sending is an action of a communication channel. The act of sending should be independent of the message type. I don’t want to implement Send.vi; I want to implement Write.vi. How will “Must Implement Send.vi” feel about that? Also, what about messages that have no data, and thus don’t need a creation method of any kind? They don’t need to implement Send or Write.
-
I don’t know why that caused you problems, but always try and use the Default Data Directory for saved files, since you can rely on having write access even in an executable.
-
I do have an example of a parent-class restriction that I wish I could make. I have an abstract “address” object that defines a method for sending a message. The framework that uses this parent assumes that “Send.vi” is non-blocking (and reasonably fast). But there is nothing stopping a child-class being implemented with a blocking enqueue on a size-limited queue, other than documentation.
-
One of the topics in the thread following this post by MattW is a possible reduction in performance due to LabVIEW needing to check if the dll path input has changed between calls. In this later post by me I explained why I switched to using an in-place structure: "I found through testing that some of my subVIs ran considerably slower than others, and eventually identified that it was do to details of how the class wire (from which the library path is unbundled) is treated. Basically, a subVI in parallel to the CLN node (i.e., not forced by dataflow to occur after it) would cause the slowdown. I suspect some magic in the compiler allows it to identify that the path has not changed as it was passed through several class methods and back through a shift register, and this magic was disturbed by the parallel call. This being a subtle effect, which future modifiers may not be aware off, I’ve rewritten the package to use In-Place-Elements to access the library, thus discouraging parallel use." Opps! I really should document more. This was only my second “wrap a C dll” job, and the first time I’ve used “MoveBlock”. The issue is the fact that C strings have an extra 00 byte at the end and thus are one byte longer than their LabVIEW string length. I’m not sure I’m doing it correctly, but in “Pointer-to-C-string to String” I’m walking along the string to find the 00 byte, while in the other MoveBlock uses I’m getting the exact string length from sqlite. Check that you are “reseting” any statements when finished (or you’ll be holding a Read lock on the database file), and that you aren’t holding an SQL transaction open (a Write lock). — James
-
Could you post some code illustrating the problem? Or images of your producer and consumer code? I can only guess that your holding a lock on the database open somehow.
-
Variant Config: format timestamps in human readable form
drjdpowell replied to d_laub's topic in OpenG Developers
I wonder if anyone has ever saved Timestamps needing better than millisecond precision in a config file. That would be the potential issue with this suggestion. -
Hi, You have a call to a missing xnode: "Minimum Array Size.xnode" in your “Toolbar.xctl:Set Toolbar Images.vi"
-
I assume you meant “Must Override”; I don’t use that much, but I’ve never had experience with writing parent classes for other designers to make children of, so I can’t really comment on that. As far as “Must Implement”, I can’t really think of a good use. Child classes can be used for purposes that are different from what the designer of the parent class envisioned, so adding restrictions at that stage seems inappropriate. Especially ones that can be easily broken by adding a not-to-be-used extra methods (what icon glyph should we have on VIs never meant to be called but needed to satisfy misguided restrictions?).
-
More than that. The IPE makes explicit what the compiler tries to do anyway: minimize copies. In fact, the IPE’s real benefit is as a guide to the programmer in writing code that can be done in place, rather than actually allowing in-placeness.
-
Thanks, it’s working fine now.
-
References deallocate when their owning VI hierarchy goes idle. When calling by reference synchronously, as your doing, the dynamic VI is running under the hierarchy of its caller. When one uses the asynchronous methods (“Run VI” or ACBR Fire-and-Forget) then that creates a new VI hierarchy. Added later: using ACBR Call-and-Collect also creates a new hierarchy (I’ve not used it before); the following mod causes the reference to deallocate. You can figure out what hierarchy a VI is running under by using “Call Chain”. With the original version, the call chain of “ThrowDVR.vi” showed it to be running as a subVI of the calling VI.
-
Shared clone reentrant execution. How can I get clones shared?
drjdpowell replied to _Y_'s topic in LabVIEW General
Perhaps it would be best if you explained what you’re trying to do.- 4 replies
-
- asynchronous
- reentrant
-
(and 2 more)
Tagged with:
-
Looking at this one, I would get rid of the child classes entirely and just have two VIs, “DisplayMessage-Bool” and “DisplayMessage-Numeric”. But this is perhaps because the example is (as most examples are) a very simple case. Even with child classes, though, I would just rename the methods. I’m not sure it is desirable to "contractually require functionality in subclasses”. That’s the author of the parent class trying to constrain and dictate the design of every yet-to-be-thought-of child class. Too easy to over-constrain. “Must override” and “must call parent” are different in that they are often actual requirements to make the child class function with parent-type code, and thus it is reasonable for the parent’s author to dictate this.
-
Just my two cents, but as the designer of a child class, I wish to have my child objects function properly in code written for the parent (and thus am interested in overriding and/or calling parent methods where required), but I am not actually interested in being required to do things with code written for the child.
-
Shared clone reentrant execution. How can I get clones shared?
drjdpowell replied to _Y_'s topic in LabVIEW General
The “shared clones” setting affects operation of statically-called VIs (such as an ordinary block-diagram use). Dynamic use depends on the options to the “Open VI ref” function; in your case option 0x8 creates a new clone with each use (with “auto dispose ref” you are destroying the clones and just reusing the clone numbers in new clones). To use “shared clones” dynamically, look at the NI example "AsynchronousCallAndCollectUsingOption0x40.vi”. — James- 4 replies
-
- asynchronous
- reentrant
-
(and 2 more)
Tagged with:
-
I was just recently sorely wishing NI-IMAQ had by-value image frames. — James PS to manigreatus> have you considered turning it inside out; make a by-value object and keep it in a DVR if (and only if) your application needs it?