Jump to content

John Lokanis

Members
  • Posts

    797
  • Joined

  • Last visited

  • Days Won

    14

Everything posted by John Lokanis

  1. One thing I have noticed is the issue appears to only occur after I run the code in the two projects. Part of the code does open an app reference connection to the other project so they can communicate (as if they were two EXEs on difference machines). I do cache that reference, but once the applications are stopped, I close that reference. Even if I did not close the reference, it should get cleaned up when the VI stops. And it certainly should clean up if the VIs and the projects are closed completely. I am not spawning some daemon to maintain the references. Seem like this might be a bug in the garbage collection routines.
  2. I have been seeing some weird behavior and was wondering if this is a known issue or if I have discovered something new. I have two projects that share several libraries and classes. One is a client application and one is a server. In order to test my code, I need to open both projects at the same time and run the main VIs. When I open the projects, the common libraries and classes are locked and I cannot edit them. So far, this appears to be normal. Where it gets strange is when I close one of the projects. If I have run the VIs to test something and then stopped them, closing the owning project of one of the main VIs DOES NOT cause the VI to also close. The correct project name is still indicated in the VIs window (lower left) and the project is clearly closed but the VI is still hanging around. The second thing that is weird is the common libraries and classes remain locked. Even closing the other project and returning the to the start-up screen does not correct this. The only way to edit those files again is to close LV completely and then reopen it. This is getting a bit tiring and I am just starting to develop this project. I am working with LV2012f3 but have not yet tested this in the 2013 beta. (I really do not want to port the whole project over at this time). Any thoughts? Anyone else seen this? I checked the known issues link and did not see anything related. http://www.ni.com/white-paper/13993/en thanks, -John
  3. I finally completed version 1.0 of my messaging system (or messaging architecture if you prefer that nomenclature) and I figured I would post it here and see what mistakes other can find in my approach. My basic goal was to build something that could replace the old school messaging in my pre-LVOOP applications. So, I wanted something that allowed for flat messaging (all processes are peers and can direct message each other) and had some type checking on the messages (I replaced the old typedef'd enum and variant with a message class). I also wanted it to be easy to extend with additional features, such as a message log or the ability to send messages between application instances. Along the way, I added a way of building hierarchical message systems like Actor Framework. I also added subscriptions like JAMA. And I tried out dynamic processes and well as static ones. I am attaching a series of example projects, each one contains the core message architecture components so if you unzip them all, it will overwrite those parts each time. The basic concept of the architecture is comprised of four components: The system class defines the overall functionality of the message system The message class that all messages inherit from The transport class that defines the generic interface for sending and receiving messages The process class that creates the message handler. (This is roughly equivalent to an Actor in AF.) The examples demonstrate remote messaging, dynamic processes, hierarchies of processes and message subscriptions. Most basic example: Message System Basic Example.zip Examples for demonstrating client-server network messaging: Message System Client Example.zip Message System Server Example.zip Example of dynamically loaded processes: Message System Dynamic Process Example.zip Example of a hierarchy of message systems (like AF): Message System Isolation Example.zip Example of message subscriptions (like JAMA): Message System Subscription Example.zip Please comment (good or bad) on the system overall and how it is organized. I am sure there is lots of room for improvement. Thanks for the feedback! -John ps. If you have any ideas for what to name it, let me know, YAMS? (yet another message system) TUMS? (the ultimate message system ) Any other ideas?
  4. Just passed the CLA-R at the #CLASummit. Now I can relax and enjoy the rest of the presentations!

  5. Here are two new ideas I added from discussions at the CLA Summit today: http://forums.ni.com/t5/LabVIEW-Idea-Exchange/All-build-able-targets-should-have-versioning/idi-p/2336172 http://forums.ni.com/t5/LabVIEW-Idea-Exchange/Version-of-components-should-be-available-to-the-installer/idi-p/2336192 Please kudo!
  6. If you think of each process (Actor) as it's own state machine, it makes sense to link them together with async messages. I guess it is more of an interrupt-able state machine, however. Personally, I like my system because my transport can be overridden with different implementations. For example, it could be a notifier or even an array of notifiers to allow many-to-one lossy messaging. Or it could be a VI Server transport to send a message to another application.
  7. Dave: Yes, that is basically it. When the parent quits, a local user event is fired to tell the UI loop to quit. Yes, all my "actors" inherit from that parent. Think of it like the Actor Core in AF. The parent handles all messages for that 'Actor'. It also contains all state data. Inside the parent code, I use dynamic dispatch to execute the various messages received. The UI loop is a 'helper', not another 'actor'. I have implemented override-able error handling within the parent message code. My 'helper' UI loop simply sends errors to the message handler to be dealt with. It occurs to me that my only solution might be to have the 'helper' UI loop call the error handler directly instead of passing it to the message handler. That might mean I cannot reuse my error handler method as easily as I wanted to. Also still leave me with the need to stagger the shutdown for the error logger so it can catch any shutdown errors from the other processes.
  8. As for sync/async, I handle this by having a request message that contains the name of the sender. The receiver then executes the message, gets the requested data and then sends a different message to the requester with the answer inside. The requester executes this message containing the data, taking whatever action needed the data to perform its work. This allows the requester to perform other actions (like a shutdown) while waiting for the data it requested. (dammit, not you got me going off topic... )
  9. Just to clarify a few points: I am not using Actors. I have created my own messaging system based off the way I did things pre-LVOOP. All my processes (Actors, if you will) are peers. There is no top level. They can all message each other directly. All messages are async. The issue really is when one of these processes contains more than one loop running in parallel. I took my design from the examples for implementing a UI with AF. The UI code has its own loop, but the code also calls the parent class in parallel where the message handler is implemented. The issue comes from trying to deal with errors at shutdown between the child implementation containing the UI loop and the parent message handler. I understand Dave's solution and I agree that sequencing a shutdown makes sense among the various processes (Actors) but I am still stuck with this case where we have overridden the parent message code to add a UI. It still seems like there is no clean way to deal with this.
  10. Just to steer this back on topic, I still do not see a way for an 'Actor' that implements parallel loops to deal with an error when shutting itself down. The AF uses these parallel loops to implement user interfaces. But, if the UI code generates an error, it must send it to the message handler loop to process it. And on shutdown, that loop has stopped. To be more specific, the user commands the UI to shutdown the system. The UI loop broadcasts the shutdown message to all processes. One of the calls to a different process fails because of some error with its message transport. That error is returned from the 'send to all' call up to the UI loop. The UI loop then tries to send that error to its message handler but since it received and executed the shutdown message, it is no longer running. The end result is I am unaware of a bug in my code where one of my processes has a bad message transport (for whatever reason). You all seem to be telling me that I should just ignore this issue. I would prefer to find a solution but it does not look like there is one.
  11. How does your error management work? Do your parallel processes handle their own errors or do all errors get dispatched to a central error handler? At first I planned to use a central error handler, but that would create a bottleneck that would block all processes when many errors occurred at once and could lead to deadlock. So, instead I have each process handle its own errors and only use a central process for logging. But, this leads to my current problem of the process not being able to handle its own shutdown errors. I could just ignore them (that is effectively what happens now) but I am concerned that would mask other issues.
  12. I am trying to solve a bit of a chicken-egg issue with my message system. Since I think this would apply to any message system, I would like to hear how others have addressed this issue. In my message system, each parallel process has a message handler loop that receives and executes messages. A process can also have code that runs in parallel with the message handler to implement additional functionality, such as a UI loop that handles events. If an error occurs in this UI loop, it sends the error to its message handler. The message handler then executes the message with the error information, outputting the error as if it happened within the message loop. This then propagates to an error handler that executes specific error handling code for that process and then sends the error info to an error logger process. I also have implemented a broadcast message to shutdown the application. This sends the shutdown message to all processes at the same time. The problem I am running into occurs if an error is generated in the UI loop when it tries to send the shutdown message. That error is not getting handled. This is because the message handler gets the shutdown message before the UI loop has a chance to send the error data. So, there is nothing listening to the error message. And even if it was still listening, the error logger process has also already shutdown so the error would not be logged either. So, any ideas on how to solve this? How do you deal with this in your messaging systems? thanks for the feedback, -John
  13. Will the icon editing feature return soon? Trying to use this with LV2012 and really need that feature.
  14. Saved for 2011: Drag to Snap off Window 2011.zip
  15. Thanks for the ideas guys! I have put together my solution pulling from all of them. I decided to make the child window deal with the mouse tracking instead of the parent. So, once it it created, it is on it's own. Seemed simpler this way and frees up the parent to do other things. I tried to eliminate all polling by using the mouse enter and leave events but a fast mouse movement could still mess things up so I added the timeout polling to make it smoother overall. The target for this code will have the child subscribe to the same message stream that the parent uses to update each row of the MCLB, but with more details displayed. Should make for a nice UI. Drag to Snap off Window.zip
  16. Ok, first, I don't even know if this is possible. I have been messing with it for a few hours and have hit a brick wall. I hope someone knows a trick or two to help me make this work. Here is what I am trying to do: When a user drags on a row of a MCLB, I want to dynamically open a VI under the user's cursor (their mouse button is still down) with 50% transparency and allow them to continue to move the mouse to drag the new VI's front panel to someplace on the screen and then release the mouse button. At that point, the transparency will return to 100% and the window will act normally until they close it. The goal here is to allow them to access additional data that is related to the row they dragged on. The problem: Opening the VI a the location of the cursor when the drag starts is not a problem. But getting it to track the mouse until the button is released is not working for me. I cannot find any way to do this within the methods that LabVIEW offers. Perhaps there is a .NET or Win32 solution? thanks for any ideas (or for telling me what I want to do is impossible). I will post a solution here if I get it working. -John
  17. I have been asked to implement some sort of online/integrated help system into my executable. I have not done anything like this before. (In the past I have just written word docs and published them on the internal network) I was wondering what the best practices were for doing this. A few ideas I had were: Building .chm files and then linking them to controls and menus in my application. (not sure exactly how to do this). Using tip strips to supply documentation. Using a pane on the window to display help messages when requested or when hovering over certain controls. Linking to a Wiki on the corporate network. I would prefer a solution that was mainly 'on demand' so advanced users would not be bothered by obtrusive help messages. Have you implemented built-in help? What worked best for you? Thanks for your ideas! -John
  18. It was the lack of error dialog that was weird. I understand why the cast did not work. Still, it is a bummer that I cannot extract a parent object from the child object without creating a parent object to feed into the to more generic node.
  19. ok, so this is weird. If you take the grandparent wire with the parent object riding on it and cast that to the parent type, you can use the parent accessors to get at the data in the parent object. But, if you take the grandparent wire with the parent object riding on it and you cast it to the child, then try to use the parent accessors available to the child class (I made them protected), you don't get the data. It comes back empty. Turns out, this is because the cast fails. But this was not obvious to me at first because I did not get an error message, even though I have automatic error handling turned on.
  20. That s what I did. But that means I needed a static parent object on the BD of the child method. I assume that means I had to allocate the memory for the parent's private data even though I did not use it. Seems inefficient to me. I would rather use the child wire to accomplish that. But this gives me an idea I need to go try now...
  21. The architecture I am trying to design is one of a process that has a defined API. So, instead of having a method for each thing the process can do, it has a message (API call) that it can process. So, it made sense to me that these would be children of the process since they were exclusive to the process and operated on the process' private data. Also, by having them be children, I can use the inheritance mechanism to allow my message system to detect what process owns them and then route the message to the process using its chosen transport automatically. Again, this may turn out to be a bad idea, but I am going to try going down this road as far as it will take me until I make it work or decide it is the wrong road. So I have created those accessors in the parent, but the wire type coming into the child is of type grandparent. So, I don't have access to the parent methods without casting it to the parent's type. I was hoping there was a way to do this using the child class wire. But I cannot sort out how to do this.
  22. Well, it is kinda complex, but here goes: I am trying to make a messaging system that uses the class hierarchy to route messages and has a plug-in type of implementation for routing methods. So, I have three main classes: System, Process and Transport. System holds a DVR containing an array of Process classes. Process holds a Transport object. Specific transports types (local queue, remote network message, notifier, etc) inherit from the transport class. Specific processes inherit from the process class. Each specific process class has child messages that implement create, send and execute methods. First, you instantiate an object of type System and create the DVR to hold the data. Next, you create a transport object for the specific type of transport you want a process to use. You then create a object for the specific process that will use that transport and store the transport in the process's (parent) private data. You also add this process object to the system object DVR. Later in your application, you create a instance of the specific process (can be the same as the object used to set the transport, or just another instance) and you set any initial conditions (this specific process, called the parent in the original email, stores any data needed to be accessed between messages). This then passes to a loop that waits for a message using the transport type set for that process and then calls the execute method for the message sent. The advantage of this is almost everything in the architecture is reusable. You just define the specifics by creating you specific processes and their messages and a transport implementation. The disadvantages are you can only have one implementation of a specific process class in each application instance. The other disadvantage is I cannot figure out how to cleanly access the data in the specific process (the parent) from within the execute message method. I have for now cast the process object to the type of the specific process but I would rather do this a better way. I included a zip of the demo project so far. Feel free to tell me this is a crazy way to solve this problem. Message System.zip -John
  23. I have a hierarchy of classes. Call them Grandparent, Parent and Child. I have a dynamic dispatch VI in grandparent that child overrides. In the child implementation, I want to access data in the parent class control. The template in the grandparent has two inputs of type grandparent. The dynamic one and a static one. The dynamic one is used to dispatch to the correct child. (this is because grandparent has more than one parent sub class and these have more than one child subclasses) The static one is used to pass in a parent object so the child has access to its data between calls. (the child is actually a message not spawned from the original parent object and therefore does not contain this persistent parent data) What I need to do is cast the grandparent wire to the type of parent so I can access the parent's data. I could use the child to do this but how do I extract the parent class type from the child and use it to cast the grandparent to type parent? I need to do this statically as design time, not at runtime. thanks for any ideas. -John An alternative solution would involve having the child (message) object inherit the data in the parent object so I could access it via property nodes. Not sure if that is possible.
  24. It still bugs me that you only get the value change event with the DSC Module... Seems like a basic feature of shared variables.
  25. I guess no one at NI want to chime in here with some tips about avoiding the root loop issue. I know some other architectures use VI Server for messaging. There must be some ways to avoid these issues or at least mitigate them.
×
×
  • Create New...

Important Information

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