Preventing script collisions: allow only one instance per %1
Moderator: DosItHelp
-
- Posts: 5
- Joined: 16 Apr 2015 13:20
Preventing script collisions: allow only one instance per %1
Edit: I found a neat implementation, see below.
Does anyone know how to have a .bat scipt check if another version of itself (%0) is running with the same %1 I have several database deamons running and I've had mysterious data corruption issues which I was able to trace to an extra instance running. Each database has it's own workspace and remote share drive locations set in a bat file (which the main script CALLs based on the value of %1).
The database itself is written in *nix (mostly BASH and AWK, some PERL where the faster AWK lacks a capability like MD5Sums) running under Cygwin and the Batch daemons are just the glue to implement things in a Windows environment.
I'd like the script to be able to check if another version of itself is running (the answer will usually be yes) and then terminate itself if another version is running with the same %1.
I am an experianced BASH and AWK scripter and know enough PERL to be dangerous but this experiance makes my Batch scripting more unpredictable than if I did not have it, I'm afraid.
Thanks, Mike
Does anyone know how to have a .bat scipt check if another version of itself (%0) is running with the same %1 I have several database deamons running and I've had mysterious data corruption issues which I was able to trace to an extra instance running. Each database has it's own workspace and remote share drive locations set in a bat file (which the main script CALLs based on the value of %1).
The database itself is written in *nix (mostly BASH and AWK, some PERL where the faster AWK lacks a capability like MD5Sums) running under Cygwin and the Batch daemons are just the glue to implement things in a Windows environment.
I'd like the script to be able to check if another version of itself is running (the answer will usually be yes) and then terminate itself if another version is running with the same %1.
I am an experianced BASH and AWK scripter and know enough PERL to be dangerous but this experiance makes my Batch scripting more unpredictable than if I did not have it, I'm afraid.
Thanks, Mike
Last edited by Michael_Stora on 17 Apr 2015 23:55, edited 1 time in total.
Re: Preventing script collisions: allow only one instance pe
Hi Michael_Stora,
you can use lock files.
Each of your instances creates a lock file, but this is only possible when the lock file isn't created and locked by a different process.
If the lock file is already there, but no process uses it anymore, then a new process can still be started.
you can use lock files.
Each of your instances creates a lock file, but this is only possible when the lock file isn't created and locked by a different process.
Code: Select all
@echo off
set "lockFileName=%~1_lock.tmp"
2>nul (
4> "%lockFileName%" (
echo starting instance
ping -n 2 localhost > nul
) || echo Failed %1
)
echo End %1
If the lock file is already there, but no process uses it anymore, then a new process can still be started.
-
- Posts: 5
- Joined: 16 Apr 2015 13:20
Re: Preventing script collisions: allow only one instance pe
Thanks for the reply. It looks like the process list does not show %1 and shows my scripts not my their bat name but by cmd.exe (even though I see the bat name in the GUI version).
I was trying to avoid lock files because my IT department will do a patch requiring a reboot a couple times a month and lock files won't restart cleanly. I'd like a solution where the lock files vanish on restart.
Can I do a lock environmental variable? Is it possible to export a variable upward? Set seems to only work at the same of deeper process level.
Can you set up a tiny ramdrive in a bat file and use that for lock files?
Mike
I was trying to avoid lock files because my IT department will do a patch requiring a reboot a couple times a month and lock files won't restart cleanly. I'd like a solution where the lock files vanish on restart.
Can I do a lock environmental variable? Is it possible to export a variable upward? Set seems to only work at the same of deeper process level.
Can you set up a tiny ramdrive in a bat file and use that for lock files?
Mike
-
- Posts: 5
- Joined: 16 Apr 2015 13:20
A cool implementation of a volatile lock
Setx does not allow setting in the volatile environment under HKCU, so I am doing it manually:
I have a gentle quit that deletes the key:
That was fun. If I log out or the machine restarts, the locks disappear.
Mike
Code: Select all
@echo off
C:
chdir C:\where\I\am\going
IF "%1"=="" ( Set "myvar=default" ) ELSE ( Set "myvar=%1" )
REM Create a key in the volatile area of the current user registry as a lock.
REG query "HKCU\Volatile Environment" /v %myvar%"_Lock" >NUL 2>NUL & if errorlevel 1 (
REG add "HKCU\Volatile Environment" /v %myvar%"_Lock" >NUL 2>NUL
REM Create the key as a lock.
goto :START )
REM if the key does not exist (error) we are good.
echo ####### WARNING ####### WARNING ####### WARNING ####### WARNING ####### WARNING #######
echo It appears the %myvar% daemon is already running.
echo If you are sure it is not would you like to force it to run?
choice /t 300 /D:N /M "Default No (5 min timeout)"
echo #######################################################################################
echo.
If errorlevel 2 goto :END
:START
I have a gentle quit that deletes the key:
Code: Select all
REG delete "HKCU\Volatile Environment" /v %myvar%"_Lock" /f >NUL 2>NUL & goto :END
That was fun. If I log out or the machine restarts, the locks disappear.
Mike
Re: Preventing script collisions: allow only one instance pe
With jeb's singleTon all you have to do is end the process that locks the file and optionally delete it. A registry key is also stored inside a file so you didn't succeed in avoiding a file. Your solution is much slower. Your lock fails if the lock is not deleted, that's not good! U may want to use autoIT to implement a mutex that doesn't creates a file on disk:
Code: Select all
$handle = DllCall( 'kernel32.dll', 'handle', 'CreateMutexW', 'struct*', $tSecurityAttributes, 'bool', 1, 'wstr', $sOccurenceName )
Re: Preventing script collisions: allow only one instance pe
Does this thread help at all?
viewtopic.php?f=3&t=6133
viewtopic.php?f=3&t=6133
Re: Preventing script collisions: allow only one instance pe
@Squashman - I don't see how that post helps directly, since it is OK if multiple instances are running as long as argument %1 is different for each one.
@Michael_Stora - To further the point Ed was making, the lock files don't have to vanish upon restart - they just cannot be locked. The exclusive lock will indeed be dropped once the batch process that holds it is terminated, regardless how the process is killed - normal exit, Ctrl-C, fatal error, reboot - it doesn't matter. Your script can delete the lock file upon normal termination, but failure to delete will not prevent a subsequent server script from running. I thought jeb did a pretty good job of explaining this important fact when he stated "If the lock file is already there, but no process uses it anymore, then a new process can still be started."
Dave Benham
@Michael_Stora - To further the point Ed was making, the lock files don't have to vanish upon restart - they just cannot be locked. The exclusive lock will indeed be dropped once the batch process that holds it is terminated, regardless how the process is killed - normal exit, Ctrl-C, fatal error, reboot - it doesn't matter. Your script can delete the lock file upon normal termination, but failure to delete will not prevent a subsequent server script from running. I thought jeb did a pretty good job of explaining this important fact when he stated "If the lock file is already there, but no process uses it anymore, then a new process can still be started."
Dave Benham
-
- Posts: 5
- Joined: 16 Apr 2015 13:20
Re: Preventing script collisions: allow only one instance pe
Thanks for your patience with me. I was thinking about testing the existence of the lock file and not fact that it is locked. I did not initially understand how Jed's script and how the lock disappears when the process locking it ends.
Thanks guys.
Mike
Thanks guys.
Mike
-
- Posts: 5
- Joined: 16 Apr 2015 13:20
Re: Preventing script collisions: allow only one instance pe
My final implementation is just to add the lockfile to the shortcuts that launch the daemons from the desktop (of startup folder). I implemented a log and lockfile external to the program:
Shortcut target: C:\my_path\Databases\Code\database_daemon.bat name 2>&1 | wtee "..\logs\name_%date:/=-%%time::=;%.txt" 4>../lockfiles/name_lock.tmp
Mike
Shortcut target: C:\my_path\Databases\Code\database_daemon.bat name 2>&1 | wtee "..\logs\name_%date:/=-%%time::=;%.txt" 4>../lockfiles/name_lock.tmp
Mike
-
- Posts: 129
- Joined: 08 Feb 2016 20:25
Re: Preventing script collisions: allow only one instance per %1
I have a quick question on jeb's code:
What does the "4> "%lockFileName%" (" line do? Or more specifically, what does the "4>" do? I know the "2>" redirects stderr, but "4>"??
I could also use a bit of explanation on this solution (above). I know it is "teeing" the output (with wtee.exe) but not sure exactly what is going on. This is what it looks like to me:
"..\logs\name_%date:/=-%%time::=;%.txt" - the filename where output is redirected to (via wtee.exe)
4>../lockfiles/name_lock.tmp - what is going on here?
We have the "4>" again... What is being reditected into "name_lock.tmp"?
Is it the output from "C:\my_path\Databases\Code\database_daemon.bat " or "..\logs\name_%date:/=-%%time::=;%.txt"?
Code: Select all
@echo off
set "lockFileName=%~1_lock.tmp"
2>nul (
4> "%lockFileName%" (
echo starting instance
ping -n 2 localhost > nul
) || echo Failed %1
)
echo End %1
What does the "4> "%lockFileName%" (" line do? Or more specifically, what does the "4>" do? I know the "2>" redirects stderr, but "4>"??
Shortcut target: C:\my_path\Databases\Code\database_daemon.bat name 2>&1 | wtee "..\logs\name_%date:/=-%%time::=;%.txt" 4>../lockfiles/name_lock.tmp
I could also use a bit of explanation on this solution (above). I know it is "teeing" the output (with wtee.exe) but not sure exactly what is going on. This is what it looks like to me:
"..\logs\name_%date:/=-%%time::=;%.txt" - the filename where output is redirected to (via wtee.exe)
4>../lockfiles/name_lock.tmp - what is going on here?
We have the "4>" again... What is being reditected into "name_lock.tmp"?
Is it the output from "C:\my_path\Databases\Code\database_daemon.bat " or "..\logs\name_%date:/=-%%time::=;%.txt"?
Re: Preventing script collisions: allow only one instance per %1
As you noted, it appears to signify standard output redirection. Some programs mentioned here may help to further check that output.
And I agree, default color for LINKS on this forum better be changed to a more distinctive one from plain text color. Several times already folks didn't notice links I posted, and then asked expected question "what the heck its about?". I don't believe the golden rule is to post all links in plain text, unless someone explains why such redundancy should be a rule?
And I agree, default color for LINKS on this forum better be changed to a more distinctive one from plain text color. Several times already folks didn't notice links I posted, and then asked expected question "what the heck its about?". I don't believe the golden rule is to post all links in plain text, unless someone explains why such redundancy should be a rule?
-
- Posts: 129
- Joined: 08 Feb 2016 20:25
Re: Preventing script collisions: allow only one instance per %1
As you noted, it appears to signify standard output redirection. Some programs mentioned here may help to further check that output.
Thanks for the link- interesting reading. So I guess numbers "4-9" could be used?
And are the contents of this file: "..\logs\name_%date:/=-%%time::=;%.txt" being sent to this file: "name_lock.tmp"?