Jump to content

Stobber

Members
  • Posts

    213
  • Joined

  • Last visited

  • Days Won

    5

Posts posted by Stobber

  1. Any chance of adding support for Inf and NaN to this API? I want to move off of the native LV prims because of their rigidity with data type and missing items in a JSON stream, but I can't let go of their support for these DBL values. Maybe you can add a property node to the JSON Value class that sets whether or not to allow these values in numeric fields?

     

    Edit: Let me clarify, since playing with the API further shows that there is some support for those values. When I try this code on a stream that doesn't have the "updated period " field in its clusters, I don't get NaN out. I get the default value for the data type, instead.

     

    O0634lT.png

  2. Our team did some research last year to try to create a unified error handler similar to the SEH...but in the end...we chose to integrate our error handling as a separate state in our templates... We could not find any other way that would offer us the flexibility and reliability that we need in our projects.  We find that by including it in this way, as part of our template, our developers were much more inclined to add the proper error handling code as it was easy to do so.  Moreover, that specific code is visible on the BD (not hidden in an Express VI.)

    With this approach, it is easier to handle specific errors in each module/driver and it is almost "synchronous" (in between each cases).  This seems to be better than generating an event when an error occurred which would still only be handled when your code gets back to the event structure.

    The idea of objects and more complex error handler built in a smarter subVI is nice but we have given up on finding the silver bullet and went for a practical approach that work well in our code.

     

    Sounds like you made the same discoveries I did through field testing! A FSM executes state-check logic on every "clock tick", so it's still synchronous error handling. I suspect you're usually aborting normal logic downstream of an error and letting your "error case" do its work before executing the intended logic again or changing state and executing other logic. This all follows what I think is the only realistic way to address errors in LV run-time logic: deal with them as close to the code that threw them as possible, so you have the "context" of that code available to your handler. And yes, providing a template for handling -- along with maybe a couple of very common generic handlers that get used all over, like "log and clear" -- is the only realistic way to spread error handling know-how to an entire team. Each handler has to be (at least somewhat) custom, so you can't reasonably expect to create an all-purpose error handler for direct reuse.

  3. You know one thing to think about is no matter what type of changes are made to error redesign, there is going to be more overhead than the current implementation....All of this is going to have more VIs to load into memory, and more processing power to perform actions.  And someone, somewhere is going to complain that they don't want all of that extra fluff when the 3 element cluster (or just the code) is all they need.

     

    Who says a redesign has to bolt on fancy new features that hog memory or demand extra CPU cycles? A totally functional redesign might just look like removing the Boolean from the cluster and defining a standard set of tags for segmenting metadata in the string!

     

     

    There may be a tiny overhead only when a listener is attached but since people nowadays seem to be throwing messages around like confetti; I don;t think they can complain about a couple of really useful ones when something goes wrong..

     

    Are you still clinging to the same computer you had when that dusty old copy of LV 7.1 was released? :P  Memory and CPU have gotten so big/fast that architecting applications with async message-based processes basically comes for free these days.

  4. Frankly, I don't think error handling code will ever be effectively abstracted to a framework or set of reuse components. The appropriate handler for each error in a finished app is too dependent on the data structures and running logic of that particular piece of code. The best I think we could do for one another is to create tutorials with example code for people to learn from.

     

    It's the structure of the error cluster and the information it carries that stands to be improved. Standardizing what goes into the string would be nice, even if it's just a set of established tags or formatting that differentiates one section of data from another, so each team can embed whatever custom information they like without stomping on anyone else's. Defining a zero-allocation structure for memory-critical RT code would be really nice, too. I should finally to look through cref's slides from years ago...

  5. Back on-topic: (No worries, hooovahh!)

     

    I used and studied RyanK's CEH back when he published it. I found two major (IMO) problems with the approach:

    1. CEH handles errors asynchronously
      Based on my experience as an app developer, I believe error handling should be done synchronously. ("Handling" involves clearing an error and responding to it gracefully, even if that response is to ignore the error or translate it into other information like a "timed out" Boolean parameter.) If the error can't be handled sync, then it can be reported to a higher-level entity async for logging, display to an operator, or handling at a broader scope than the "thread" (LV loop) that threw the error and failed to handle it locally. Broad-scope handling actions in my RT apps often look like resetting the application's operating mode or forcing output signals to fail over to a safe state until the operator reviews and clears the critical error.

      I think ShaunR's suggestion of an "Error Event" has the same flaw: events are asynchornous in LV. What I think we need is an "Error Callback" so it's handled synchronously with context-sensitive dispatch of which handler to use. On that note...
       
    2. CEH is insensitive to context
      An error code has no context whatsoever. Error 7 ("File not found") might be safely ignored in some processes, but it might represent a critical failure in others. It gets thrown by native APIs that have nothing to do with file access, too, so you might not think to deifne a general-purpose handler for code 7 that addresses an unexpected API or app process. Errors should be handled as close to where they're thrown as possible, so the handling code can be written in the same design context as the code that generated the error.
  6. I went mucking around inside General Error Handler.vi and am aghast at what I found. It seems like error definition is split between error code lookup (defined in error files) and extra information jammed into the description string using bracketed tags (like call chain and suggestions for handling the error). Why we're forced to handle specific error codes anyway is beyond me. There isn't any way of knowing which codes will be thrown by a given function, and many of the first 100 codes are reused in mysterious ways all over NI's APIs. (e.g. error 7 coming from a property node inside the VI that establishes an SMTP connection)

     

    Surely there's a better way to organize and transfer information about something having gone wrong? I realize that LV will always be dependent on returned error values from each function instead of cooler systems like exceptions, but there still seems to be a lot of opportunity for improving HOW those errors are encoded, decoded, and handled.

     

    Has anybody spent time thinking about this? Should I just put the rug back down and pretend I never looked under it?

  7. I was mistaken when I said DBL should convert to Unix time in my bug report. It will still help me (and everyone who writes to a db using LV and reads from it using other tools/languages) to convert LV time to the correct format for whichever datatype is used when storing the value.

    • Bind Timestamp (Real) should convert to Gregorian time
    • Bind Timestamp (Text) should convert to ISO8601
    • Bind Timestamp should stay LV time, since it's a BLOB
    • I'd like it if you added Bind TImestamp (Int) and wrote Unix time with that

    Edit: My use case is to write to the db using a LV app on cRIO, then read from it using modern data analysis and visualization tools. Using LV to display and analyze datalogs is like cooking dinner with a hammer and a campfire. So this fix will very much help me. Right now I'm using Bind Integer as a workaround.

  8. Rolf beat me to it. One addition: SQLite does have a defined epoch and constraints. Actually, it has several epochs depending on the datatype of each time value (see https://www.sqlite.org/datatype3.html#datetime ).Their implementation of helper functions that  manipulate time using an old C library is described at the bottom of this page: http://www.sqlite.org/lang_datefunc.html

     

    Note that trying to use any of the library functions on that page will result in storing time as a string instead of the column affinity, unless you cast the returned value.

     

    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.

  9. I appreciate the tip on INSERT OR IGNORE, but I'm concerned about SELECT not working in a prepared statement because I intend to write more statements like it. I noticed that "Valid Statement" was FALSE....which is obviously untrue. Maybe it's an issue with executing against the Linux SO that NI distributes?

  10. I'm having trouble binding parameters to a SELECT statement.

     

    This is the statement I want to execute (including a valid param value): SELECT id FROM variable WHERE label = "BooleanTestVariable";

    When I run that statement in my database viewer, it returns a row with id = 1.

     

    When I run my code (pictured below) with this string on Prepare.vi, no rows are returned by First Step.vi: SELECT id FROM variable WHERE label = ?

     

    I noticed that string values have to be quoted in Execute SQL.vi, so I tried that: SELECT id FROM variable WHERE label = "?"

    But it returns "Error 402884 occurred at datalogdb.lvlib:Define Test Variables.vi on "SELECT id FROM variable WHERE label = "?"" Possible reason(s): bind or column index out of range"

     

    What am I missing?

     

    My code:

    0VhsoxL.png

  11. I'm trying to use it on a Linux cRIO. The API VIs execute without errors (even the individual CLF nodes), but nothing gets written to disk. Even the "Example 1 -- Create Table.vi" example doesn't work when targeted to my cRIO. It does create a file on my Windows system.

     

    Edit: Realized that SQLite3 wasn't installed on the target. Ran "opkg install sqlite3", which put the executable in /usr/bin, but that doesn't work like a shared library for the API. I think I need to get a .so onto the target and point to that in the "SQLite Library Path" parameter.

     

    Edit 2 (SOLVED): The library is /usr/lib/libsqlite3.so . Provide that path to the API when opening/creating a file, and everything works great.

  12. Something like this but with better reference handling?

     

    That won't work if the probe VI doesn't update its FP until called again. It'll take an XControl...or something easier and more maintainable and easier to provide support for, like launching a "debug panel" that runs in the app.

  13. Custom probes only update when the execution path runs through them, right? I have a custom probe that peeks behind a DVR and exposes lots of debugging information about the daemon VI the DVR is shared with. My application touches the DVR once and moves on, meaning the probe only updates that one time and then fails to give me information about the daemon later. How do I design the probe to continuously update without the app execution passing through it repeatedly?

×
×
  • Create New...

Important Information

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