LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

What happens if I change a VI (to reentrant) located in vi.lib? Also, Q's about reentrancy design/philosophy.

I'm working on a database module and want to be able to handle concurrent requests for data and execute parallel queries. However, it seems the Database Connectivity Toolkit (DCT) VI's are non-reentrant. The ones I'm looking at specifically are Execute Query and Fetch Recordset. I do NOT know much about what's under the hood with regards to what all is happening in the line from DCT VI's>>ADO>>DAO>>ODBC>>Database, so please go easy on any incorrect notions I have and enlighten me where necessary.

 

My assumption is that the Execute Query vi is not really a problem because it completes quickly. That said, if there's no problem with changing it to reentrant maybe it makes sense to do that anyway. That said, the Fetch Recordset vi does seem to have a portion that takes the lion share of time when querying.

 

So my questions are:

 

1) Should I change it to reentrant? Is my thinking sound or flawed?

2) Do I need to make every subvi of Fetch Recordset reentrant also? This might be impossible as some of the lower level subvis are locked. However, I have noticed that the major time consuming task appears to be within the Fetch Recordset vi itself, so maybe it's ok to just change this one vi?

3) I really don't know how LV works in terms NI libraries and the runtime environment. If I change the vi to reentrant, does it not matter in a built application b/c my app will use the Fetch Recordset vi in the runtime PC's vi.lib which is still non-reentrant? I just don't know how it all works. I can't seem to figure out how to make a copt of this vi and save it elsewhere leaving the original intact. Should I even do that if it's possible.

 

On a more general philosophical topic, what are the implications of making a parent vi reentrant that contains 1 or more non-reentrant functions? I imagine that ideally you want reentrancy all the way down the call chain but while considering this on my commute yesterday it seemed to me that if the subvi's don't take much time to execute versus some process intensive code in the parent vi (the part that is the real impetus to desire parallelism), then as long as there weren't a ton of clones existing at once (there won't be more than a handful in my database project) then it would be fine as the subvi's would lock>execute>unlock fast enough that they would be readily available to all clones and certainly a fraction of a percentage of the overall processing time.

 

For this post, assume that the database itself will service parallel read operations (I'm confident it does). Again, I really don't know much about the call chain from DCT VI's>>>ADO>>>ODBC>>>Database, so if there's something there that would force singleton behavior that would be unfortunate but I have a hard time imagining that would be the case, at least for the ADO>>>ODBC>>>Database part... But who knows?

0 Kudos
Message 1 of 4
(2,694 Views)

1) There's probably a good reason they're not reentrant. The typical reason (I don't know about this specific case) is that somewhere under the hood you're making a call into a library that retains state between calls, and so making multiple calls simultaneously can give you junk out (or break things disastrously). Try it if you want, but check carefully you didn't completely mess up your data fetching (and perhaps check carefully that you're not making a mess of your real data).

2) If you make A.vi reentrant and subVIs B,C and D are all non-reentrant, then A can be called multiple times at once, but each version will wait until B, C and D are not being called by something else to be able to use those VIs. Conceivably the first could call B, then the first could call C whilst the second (A2) called B, and so on, but that's the basic idea.

 

3) To make a copy and replace it in your existing code, open the VI and choose Save As... > Copy - Substitute Copy for Original. This will leave the original in place, create a copy somewhere else, and update your code to call the copy instead. Note that the copy will still reference the same subVIs as the original, which is likely not what you want in general (but in this case could be ok?). The "Duplicate hierarchy to new location" option excludes vi.lib, so that won't help you...


GCentral
0 Kudos
Message 2 of 4
(2,646 Views)

First, if you ever want to change anything in vi.lib, ALWAYS copy it to user.lib or some other location, modify it there and use that code. NEVER change anything in vi.lib itself.

 

What we found is that buried deep in the DB toolkit everything gets single threaded. We tried the experiment of marking things are re-entrant and it didn't work. We ended up abandoning the DB toolkit and using a TCP base library. We are communicating with a MySQL database which has a well defined API. We got the initial library from some other forum members and then extended it since the original was not a complete solution. What DB are you trying to communicate with?



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 3 of 4
(2,642 Views)

Not all DB's are crated equal.

 

The more robust implementations will do the selection on the machine serving the DB while the more basic versions will transfer a bunch of stuff and the crunching takes place on the machine making the request.

 

So in the case of the more robust DB's you have to make sure the result you are fetching is actually the result of your intended query... and that is where the non-reentrant VI keeps things consistent.

 

If you really want to go down that path you launch background exe's that execute your queries and return the results via whatever mechanism that you are comfortable using.

 

And if you go that route make sure your DB team are aware of what you are doing. Spawning off 500 exe's hammering a DB may not make you very popular.

 

G-Story time

 

Spoiler
Years ago another contributor to this forum (Chiley-Charley) and I were tracking stats for users of this forum. We wrote code that used FTP to grab info on all of the active users, parsed the results, and moved on to the next user. The speed of that collection process was rather slow. We speeded it up by cloning off a bunch of sub-VIs that would gather the info from multiple users in parallel and it greatly decreased the run-time.... until our traffic triggered a denial of service... Smiley Sad

 

Ben 

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 4 of 4
(2,613 Views)