Jump to content

drjdpowell

Members
  • Posts

    1,969
  • Joined

  • Last visited

  • Days Won

    172

Posts posted by drjdpowell

  1. We use networked shared variables and also ActiveMQ (an implementation of Java Message Service) -- via a custom LabVIEW interface -- for messaging much as John describes. ... John, you might want to look at the publish-subscribe approach. Isn't publish-subscribe communication really what you are after? That seems to me to be more or less what you are describing.

    I played around with RabbitMQ a bit yesterday. Getting a RabbitMQ broker installed and running was quite fast and easy. LabbitMQ needs polishing and is lacking in documentation, but seems pretty solid. RabbitMQ should do publish-subsribe very cleanly, especially with its “topic” exchange type where one can specify the messages one wants by pattern. And at least according to the documentation, one can cluster multiple computers into a single message broker, providing redundancy against single-point failure (though with the possibility on failure of some messages being delivered twice).

    — James

  2. Thanks DRJDPOWELL for posting the notifier example. How would I correctly stop this VI? I tried adding a "stop" event case and I think only the producer loop stopped. I also tried adding a "release notifier" outside the same while loop, resulting in an error 1.

    Release the Notifier in your “stop” event case in the top loop; that will cause an error in the “wait on notification" in the bottom loop, causing it to shutdown (since the error is wired to the stop of the loop).

    I personally would remove this and the inner loop completely unless you really want that loop inside the consumer to execute as long as the switch is on.

    That was the use case of the original post; to start and stop listening on FIFO for incoming data. I use secondary loops like this for things I have to wait on, such as a TCP connection. If instead you want a second loop to execute commands from the primary loop, then you are better off using a queue. But you can still use the destruction of the queue in the primary loop to trigger shutdown of the secondary.

    • Like 1
  3. I still think this is a "half" solution. With variants, we should just be able to wire an output to an indicator and it should just do it without explicit conversion.

    Well, currently they do let wiring to an indicator define the data type. Unfortunately it has to be directly wired, with no other structure in between, which limits its usefulness:

    post-18176-0-21219800-1354278270.png

    And you still need the “Variant to Type” primitive. But where would type-conversion errors go otherwise?

    Also, the first thing I would do, if my idea was implemented, would be to make a “Variant to Numeric with Units” VI that would enforce matching units between the Variant and the supplied type. Your idea wouldn’t help with that.

  4. That just creates a single point of failure. Something I cannot do in this system as the cost of it failing is expensive. I can live with one server going down or one client, but not something central to everything.

    One thing to possibly look into is LabbitMQ, a LabVIEW wrapper of RabbitMQ, a message broker system. An already developed message system might have addressed many of your issues. Haven’t tried it myself (has anyone used LabbitMQ?) so I can’t tell how much effort it would be to set up.

    — James

  5. How so? I thought you can avoid the root loop when spawning as long as you hold a refnum to build clones off of for the lifetime of an application? Of course that implies at some point you need to open the initial target refnum, but if done at start-up, no root access should be required whenever you need to spin off a new process.

    I was going to go into that, but bailed with a “…"

    The end goal is a system where there are N servers and N clients. Each client can connect to N servers at the same time. Servers support N connections from clients simultaneously Servers 'push' data changes to the clients. Clients send commands to servers to control them.

    Maybe you should use a central message “broker”, with all servers and clients connecting via the broker. Then there is only one connection per process. I think Shaun’s Dispatcher works this way, if I recall right.

  6. Do you have an example? Seems I would have to create a listener on the receiver side for every 'potential' sender. Since the receiver does not know who the senders might be, I can't think of how to do that.

    There is only one listener. It listens for clients on a port and creates connections (one for each connected client). Those connections can be serviced either by polling through them or by dynamically spawning a connection handler for each. But there is only one listener.

  7. My question is what exactly is the difference between this and the stock downcast. I believe the downcast will also throw an error if the cast cannot be done.

    Illustration:

    A Child object on a Parent-type wire being cast into a "target" Grandchild object on a Parent-type wire will produce an error with PRTC (note that the “stock downcast” works on wire types, not the actual objects).

    The point of this is that the compiler can be certain that the object coming out of the PRTC is the same as the target object; this means it can trace through the input wire type to the output of the subVI at edit time. So if you write a subVI with Parent inputs and outputs, and connect a grandchild wire to the input, the output wire will take on grandchild type. See below an example subVI I made recently using PRTC; note that I can “pass through” wires of different object types (the actual subVI uses LVObject inputs and outputs).

    post-18176-0-10214500-1354029984.png

    I should add that the PRTC is only needed if the compiler cannot already tell that the object out is the same as the object in. In my subVI above, I’m receiving an object in a message and using PRTC to “cast” it as an object of a specific type. Inside the subVI, the wires are LVObject, so the stock cast functions do nothing.

    It is confusing at first.

  8. Messenger Library


    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.***


     

    • Like 1
  9. When I run the highlight execution the queue get the correct size of elements, 5 in this case, then the event structure flush the queue, and start again from element 1 to 6, 5 again but this time it doesn't trigger the event structure and the for loop keeps waiting.

    That’s because the second time around your are setting N=6, so the FOR loop needs to execute six times, but the queue only holds 5, so it gets stuck waiting.

    • Like 1
  10. Your second mistake was in wiring the buffer size to the max queue size of the obtain queue node. The top loop is filling the queue with five elements and waiting for the bottom loop to respond, which it never does because of the way an Event structure works (see below).

    Actually, he needs that to throttle the producer loop to always provide “buffer” number of elements to the consumer loop. Instead, he has a bug in setting the number of iterations of the inner FOR loop (it should be “buffer”-1); removing that, the “buffer full” locals, and adding a Val(signal) property makes the code work.

    But this is all academic as...

    This is a very over-engineered way of doing what could be done with one simple loop with “Array Subset” in it. I recommend the OP start from scratch after resolving not to use any local variables, queues, or event structures.

    — James

  11. That's right (and I have never used any software from LavaG in a commercial application). However, it is much easier to gain approval for a single self contained API than it is for one that relies on another 20 (like the OpenG).

    The JSON package currently depends on four OpenG packages: Data, Array, String, and Error. The array stuff is only used in one place that I’d like to rewrite anyway, so it is only three packages that are required. And the variant-handling stuff is widely applicable; if I wrote Variant-based APIs to be “self contained”, I would quickly wind up in a situation where I have multiple non-identicle sets of variant-handling VIs installed on my machine. Not ideal. Switching to using the off-palette VariantDataType VIs installed with LabVIEW is one option, but then if NI hasn’t put it on the palette, don’t you need to gain approval for that?

  12. Yeah. Well its got LVPOOP in it so that's not an option. :P

    Theoretically, the not-on-the-pallet VIs in vi.lib\Utility\VariantDataType should blow the OpenG stuff out of the water, as OpenG has to flatten the data to access it (expensive), but my only experience with the VariantDataType Vis is that they are glacially slow.

  13. If you can wait until next weekend, I'll replace all the openG stuff so it's a self contained lib. Just a bit busy at the moment finalising the websocket demo, but that will be finished this week.

    OK, but to me it seems silly for anyone to avoid OpenG yet use this (far, far less tested through experience) third-party open-source software. I’d rather offer the whole package to OpenG.

    Now, do it with higher performance and you’ll get me interested. :)

×
×
  • Create New...

Important Information

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