Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

File in USE and REPROCESS 2

Status
Not open for further replies.

Olaf Doschke

Programmer
Oct 13, 2004
14,847
1
0
DE
I want to recommend a good way to handle REPROCESS and error handling for the "file in use" error you encounter in multi-user applications sooner or later.

When I test parallel running clients as a stress test, be it for my new VFPTransactions or anything else, by running scripts that add/change/delete data in tables in much higher frequency than a usual application would do in multiple VFP processes, I experimented with I think all possible settings for REPROCESS.

The help topic on that is very important, its behavior is not only about retrying to get access to a file that is shortly locked (no matter if your code locks or not, write operations always cause automatic locks - another important help topic on that exists). There is one most promising mode to retry infinitely when you SET REPROCESS TO -1. But that setting fails completely when you do your stress tests that fire one SQL command after the other on tables. I see this reprocess setting polling to get file access so aggressive, that it ends in a deadlock and never succeeds.

So I regularly can tame the problem to just be a waiting time problem (unless some insert/update/append/replace/delete actually takes forever) when letting the general error handler do the retry after sleeping a few milliseconds.

Have this in the head of your error handler you set by ON ERROR:
Code:
Procedure errorhandler()
  Lparameters tnError, tnLine, tcMessage,...
  
  If tnError =108
     Declare Sleep In kernel32 Integer dwMilliseconds
     Sleep(Int(Rand()*100))
     Retry
  EndIf 
  
  * your usual error handling
EndProc

If you do this one after the other client will get file access. Play with min/max sleep times, this will surely change with LAN and HDD speeds.

Obviously the REPROCESS Setting also has to cause the error handler at least after a configured number of attempts or seconds. But forget the options about wait time, this may work okay up to a certain number of users, but attempting for one second as aggressive as VFP does is not getting you to the file access you want. It's okay to set it up for a few attempts, as secondary attempts can succeed and unbind you from putting VFP to sleep even just once, but it's also okay to keep it at the default 0. That's documented to also attempt infinitely, but you also get informed, an error handler in place changes hat behavior to trigger an error and thereby trigger the error handler. The error number you get passed in is 108 and as said it pays to put up special handling about it, see above.

Have a less troublesome multi-user experience that way. This was even in use for a decade and longer with a few hundred users base and works well.

In case of stress tests firing on dbfs very frequently many of the test clients/processes will sleep a lot and you get not much done, but no process will fail unless you get a problem with exclusive access, error 1705. That's another topic and can only be resoled at the client having exclusive access.

Sidenote: If you never used RETRY, take a look at ways you can end an error handler in, besides Return, Retry, and perhaps an often used QUIT, you also have the option Cancel and Return TO somewhere, especially Return To Master. Besides changing to suspend or go into single step mode when you run in the IDE.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Olaf, that's an interesting approach, just wondering about the:
Code:
Sleep(Int(Rand()*100))
Why the RAND()?
 
If every process waits the same time you also can easily get the effect they unintentionally and passively "sync" their efforts to get access to a file. A random wait time, even a pseudo random one will mean one client will wait shorter and try again earlier and this helps.

100 ms, or 50 ms in average, are a long time, you might even shorten this, it can pay to adjust this to whatever specific LAN your code works in.

Bye, Olaf.

Olaf Doschke Software Engineering
 
Thanks, that sounds logical.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top