Jump to content

drjdpowell

Members
  • Posts

    1,969
  • Joined

  • Last visited

  • Days Won

    172

Posts posted by drjdpowell

  1. BTW, a Database is not a good example to use for considering “actors”; a database is already well-designed for handling concurrent access, so someone reading may not see much value in introducing actors.  Instead, how about a piece of hardware that can only do one thing at once, but may be needed by multiple concurrent processes.  A part-handling robot, for example.  An actor that handles all interaction with the robot can rewritten to mediate concurrent requests, perhaps through some kind of “transaction” system.  Eg:

     

    ProcessA —> Robot: “Request robot transaction"

    Robot—>A “Transaction Started"

    ProcessB —> Robot: “Request robot transaction"

    Robot—>B “Busy; you are in job queue"

    ProcessA—>”Do action 1"

      <robot working>

    ProcessC —> Robot: “Request robot transaction"

    Robot—>C “Busy; you are in job queue"

      <robot working>

    Robot—>A “Action 1 Finished"

    ProcessA —> Robot: “End transaction"

    Robot—>B “Transaction Started"

    etc.
     
     
    The Robot Actor would either refuse any “Do action” requests from a Process that doesn’t have an open transaction, or consider such a request as implicitly being equivalent to a combined “Request transaction; Do action; End transaction”.  
     

     

     

     
    • Like 1
  2. I am thinking it might be better design for Actor B to send the data to Actor A along with the next step it should do.  That way Actor A only knows two things: How to ask for data and how to process data when received. 

    I would have Actor A attach some kind of token to its request to Actor B, that Actor B would send back attached to the requested data.  This token would contain the next step for A to do.  This way the code for A is all contained in A, and B can be more generic and service requests from multiple actors.

     

    In the framework I use, which like Lapdog uses text identifiers on messages, I usually do this by configuring A’s request to relabel the reply from B:

     

    post-18176-0-06181700-1376646166.png

     

    Here, A will receive back a message containing B’s data, but with the label specified by A (overwriting the label set by B).

  3. Query: Isn’t it the DVR (or SEQ or other similar reference) that is an alternative to the Action Engine’s uninitialized shift register, rather than LVOOP?   LVOOP is by-value, and you need something by-reference to stand in place of an action engine.  The DVR is by-ref and can be shared among VIs with different con panes, in contrast to the shift register that is constrained to one VI.  

    • Like 1
  4. For example, here's a screenshot from the 2012 QSM project template. 

     

    The thing that strikes me about that picture is, first, the fact that the queue has two writing processes, and second, that subactions of handling a message are treated as new messages for the queue.  I agree with you about the problems of this, but don’t think that this is best communicated by arguing about how to define the differences between two very similar acronyms.  I feel the same way about the “Action Engine”/FGV thing; it’s not really very productive.  

     

    I think it would be better to identify and talk more directly about the issues of message ordering and perhaps introduce more illuminating terminology, for example the concept of a “critical section”, or the database-transaction concepts of “consistency” and “isolation”.  The “Initialize” transaction is a critical section, and because it isn’t protected as such it isn’t isolated from other transactions.  Adding a different (non-FIFO) transport, that may switch the order of the two subactions, would also prevent it being consistent.  

     

    Note, btw, that a Get-then-Set transaction on a FGV/AE is also a critical section, and because it isn’t protected as such it isn’t isolated from other transactions.  Thus, these concepts are more widely useful than the definitions of QMH/MHL.

     

    — James

  5. I still believe QMH is a poor name.  It identifies the message transport's implementation--a queue.  The transport's implementation is irrelevant to your definition of what a QMH is.  Furthermore, I believe the transport's implementation is irrelevant to any well-written message handling loop. 

    A “queue” is different than a specific implementation of a queue, such as the LabVIEW in-built Queue.  User Events also involve a queue, as do things like TCP or Network Streams and the like.  In contrast, things like Notifiers do not.  So, “QMH” does not specify the transport implementation.

    Re QSM/QMH/MHL: I note that “queued-message handler” is ordinary English, while "message-handling loop” only makes sense if one understands the programming-specific use of the word “loop” to mean repeated code.  “Queued state machine” only makes sense if one uses "state” in a very strange way that doesn’t have anything to do the state of anything.   So I like “queued-message handler”.

     

    BTW, one can make a QMH that is composed of a pool of MHL “workers”, so those two terms are not necessarily interchangeable.

  6. Thoughts on just watching it:

    1) More pictures; fewer words.

    2) I suggest starting with the Message-Handling Loop or QMH (that people will be familiar with) and talk about what restrictions would make this an Actor: 

         — communicates with other code/actors ONLY via messages to this SINGLE loop.   No by-ref data sharing or other communication methods.

         — no global addressing (eg.  no “named” queues)

    3) mention “high cohesion and loose coupling”; an actor is a cohesive unit that is loosely coupled to other actors.  

  7. If you want to update the graph only after events come in, but don’t want the overhead of updating every event in a “burst”, you can put a “-1” constant inside the timeout case and wire it back through shift register into the timeout, and set the tunnel out to “Use default if unwired” so that the timeout is zero after any event other than timeout.

    • Like 1
  8. I know, people should be trained not to stop the execution that way, but this will happen. I don't want to hide this button, since it might be necessary to kill the program from time to time during development. So I'm looking for another way to handle this.

    I generally hide the toolbar on the front panel.  One can still access the hard-stop button by opening the block diagram.  I also usually capture the “Panel Close?” event and use it to trigger ordered shutdown, so a User can hit the X button to stop the program correctly.

     

    I’m not sure there is an easy way to clear the lock if this happens, other than restarting LabVIEW.  

  9. I may be missing something, as I haven’t used other OOP languages, but can't we already create “constructors” and “destructors” and get polymorphism through polymorphic VIs?  Polymorphic VIs could do with an upgrade to interface more nicely with dynamic dispatch methods, but otherwise what are we missing?  “Overloading” is not interesting to me because I don’t specify functions by typing their names.

     

    — James

     

    BTW, your “Singleton” example isn’t a singleton; I can easily call the constructor multiple times and make multiple instances of the class.  Also, I didn’t understand the “DVR cannot be used for dispatching” issue; I tried making a child class with an override and it worked fine.

  10. Playing around with Queue tester, it was interesting how most of the slow queue performance is due to attempting operations in parallel.  In a striped-down test (statistics removed) it was about 8 times faster if it was run in the UI thread (forcing serial access).  It was 0.6uS per element on my relatively slow processor.

  11. What I wanted to do now is to code a simple standalone viewer for the database so I can see what my testrig is doing while I'm in my office/at home. The problem is: when I try to run the compiled code, it simply does not work...

    It compiles and runs nicely, I have no access to the database though. Nor any error message. And I didn't even try it on another machine, it's still my lab-pc running Win7 and LV2011.

    Do you mean you are building an EXE executable?  I would suspect the problem is not getting sqlite.dll included.  Check the “Preview” page of the build and see if sqlite.dll is installed under “data”.  Sqlite.dll is part of the “Connection” class library and thus should be included, but I noticed just recently that the library, when installed with VIPM, loses it’s connection to this file.  If this is the problem, you can fix it either by opening the “Connection" class and fixing it to include sqlite.dll, or adding sqlite.dll to the “Always Included” section of the build spec.

×
×
  • Create New...

Important Information

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