10-30-2021 02:41 AM
Question: how do you handle subclasses in configuration? I very often have cases where some subcomponent can be one of multiple subtypes, each with different config info. A common example is hardware abstraction, but anything that involves a choice of child classes has the same issue. The config info will be a different structure based on child class. Maybe one child uses TCP and has an IP address, while the other has a Com Port and Baud Rate, say.
How do you handle this with your LabVIEW Clusters? How do you store config info from subclasses?
10-30-2021 02:52 AM
@Dmitry wrote:As to 'json-to-whatever' converter vs 'LVCluster-to-whatever' converter: your choice depends on whether you are OK with weak type-checking or have a preference for strong type-checking.
Just circles me back to my original point: you don't have strong type-checking through the storage format, and thus still do all the weak type checking.
11-01-2021 04:22 PM
@drjdpowell wrote:
Question: how do you handle subclasses in configuration? I very often have cases where some subcomponent can be one of multiple subtypes, each with different config info. A common example is hardware abstraction, but anything that involves a choice of child classes has the same issue. The config info will be a different structure based on child class. Maybe one child uses TCP and has an IP address, while the other has a Com Port and Baud Rate, say.
How do you handle this with your LabVIEW Clusters? How do you store config info from subclasses?
Easily 🙂
This approach does not work for 'dynamic plug-in' applications that dynamically load subslass code (plugins) from a known folder hierarchy at runtime. For this type of application one needs to use some flavor of a Service Locator.
11-01-2021 04:27 PM
@drjdpowell wrote:
@Dmitry wrote:As to 'json-to-whatever' converter vs 'LVCluster-to-whatever' converter: your choice depends on whether you are OK with weak type-checking or have a preference for strong type-checking.
Just circles me back to my original point: you don't have strong type-checking through the storage format, and thus still do all the weak type checking.
Correct. But in my case there are only two weak type-check call sites per application. In case when a class implements Loading/Saving its own configuration it is two weak type-check call sites per class.
11-02-2021 03:43 AM
Ah, so to follow my example, you would have both an IP address AND a Com Port and Baud Rate.
Re the single versus many call sites, I'm not sure that means anything, in that it isn't preventing any errors.
11-02-2021 10:17 AM
@drjdpowell wrote:
Ah, so to follow my example, you would have both an IP address AND a Com Port and Baud Rate.
Yes. But in separate clusters - each subclass would have its entire configuration cluster stored in the application configuration supercluster.
12-15-2021 08:05 AM
@drjdpowell wrote:
@WavePacket wrote:
@drjdpowell wrote:
@WavePacket wrote:
@drjdpowell wrote:
Why do you have a "database actor"? Databases are a lot more sophisticated than some dumb hardware. They support multiple clients with transactions and ACID compliance. Why not use them directly?
"Why" is that there are a few times where I want the asynchronous behavior. For example, there is a software where I want to populate query results as they come. The user is likely interested in the latest results but could infrequently be interested in old data. So I want to present the newest results first, but asynchronously continue to fill in old results as they come back. The query is long enough that I don't want to make the user wait for all results to come back.
Another possibility is that as a test proceeds, I want to asynchronously be asking the database as we go along if the test results are normal (but allow the test to continue until the database responds with a warning). Kind of like an asynch background check of the results.
Databases are already asynchronous. More capably asynchronous that you Actor is. Databases can generally support multiple Readers and Writers at the same time, and have a Transaction system to keep things straight. Your Database Actor is not able to do these things, and by putting a single Actor as gate-keeper to the Database you are significantly reducing the asynchronous capability of your App, or at least you are forced to reinvent the wheel.
I'm familiar with concurrency in databases. What I need though is asynchronous behavior in my app, but from the databases perspctive it might not need to the asynchronous connections. If I desired asynchronous behavior in my app, and asynchronous database connections would your suggestion be something like launch many copies of async VIs to launch more than one query simultaneously?
As an example, let's say we have:
Actors A, B, and C that collect data and save to the database.
Actor D that analyses the recent data and saves results in the database.
Actor E that watches the database to display if results seem normal.
Actor F that displays recent results from the db.
Actor F that displays long-term trends in the db.
All these Actors can independently talk to the database. So what is your "Database Actor" for? What does "I need asynchronous behavior in my app" even mean in this context, given that all these Actors have clear and simple single-purpose roles? Actor F, for example, may have to wait a bit for it's long-term trends Query, but it doesn't have anything else to do while it is waiting, so why would it need an asynchronous db query?
So I was rereading this thread again...and realized I got distracted by other topics and never closed off this sub-topic.
My desire for a "database actor" was that it was meant to be a reusable actor used for all cases A through F. Potentially, that desire for generality directly led to my problem of "but where does the specific syntax".
So now I'm thinking:
12-15-2021 08:19 AM
@WavePacket wrote:
@BertMcMahan wrote:
...
...
Mind if we also discuss a situation where the hardware interactions are rather test-station specific? This means that multiple test stations seem unlikely to be able to inherit the same interfaces.
As an example, one of my "hardware" actors is a database, and multiple other softwares actors have database needs which are rather specific (i.e., I need this data analyzed in this way, from the previous test). So each test station will have different database syntax.
So I'm kind of at a loss for how to separate the concerns between the multiple software actors and the single database actor in particular. Some options (maybe the nicest option is not even among this list...?):
- The softwares' actors supply the database queries they need
- (But as an example, this seems to be analogous to having Multimeter VISA commands being supplied individual test softwares, which isn't a good architecture).
- ...
So to reply to my past self (a psychologist might have word about whether that's normal or not...). I'm getting less worried about #1. After the dust settles, if a test software interacts with a database, somewhere that dependency is going to rear its head and has to be injected. I think the way forward is to make the interfaces as generic as possible, and then separate as much of the SQL syntax as reasonable.
For example, these interfaces could be wrappers of dynamic SQL where at runtime the parameters are supplied. As a specific case, I could have an interface which is for selecting all data from a table, and the tablename is selected at runtime. That seems reasonable.
That's somewhat equivalent I suppose of wanting a power measurement but first I have to tell you the wavelength of light. All the VISA syntax is under the hood, but I do need to tell you the wavelength parameter.