diff options
author | Christian Hesse <mail@eworm.de> | 2021-07-01 22:52:23 +0200 |
---|---|---|
committer | Christian Hesse <mail@eworm.de> | 2021-07-01 22:52:23 +0200 |
commit | 3f893a327d3892e5f29dacadc754b9999b91d097 (patch) | |
tree | 4e8adf326947aded9595bf68ff4a65b4d58cd667 /global-functions | |
parent | 89f8dc712001872783c8b3be7208bc1d726a12dd (diff) | |
parent | aad91d90ea3c4cbe21b5c4f61fed94aaa337bddb (diff) |
Merge branch 'ScriptLock' into next
Diffstat (limited to 'global-functions')
-rw-r--r-- | global-functions | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/global-functions b/global-functions index 63c0e21..e7080e4 100644 --- a/global-functions +++ b/global-functions @@ -904,13 +904,68 @@ # lock script against multiple invocation :set ScriptLock do={ + :local Script [ :tostr $1 ]; + :local DoReturn $2; + :local WaitMax ([ :tonum $3 ] * 10); + + :global GetRandom20CharHex; + :global IfThenElse; :global LogPrintExit2; - :local Script [ :tostr $1 ]; + :global ScriptLockOrder; + :if ([ :typeof $ScriptLockOrder ] = "nothing") do={ + :set ScriptLockOrder [ :toarray "" ]; + } + + :local AddTicket do={ + :return ($1, $2); + } + + :local RemoveTicket do={ + :local Return [ :toarray "" ]; + :foreach Ticket in=$1 do={ + :if ($Ticket != $2) do={ + :set Return ($Return, $Ticket); + } + } + :return $Return; + } + + :if ([ :len [ / system script find where name=$Script ] ] = 0) do={ + $LogPrintExit2 error $0 ("A script named '" . $Script . "' does not exist!") true; + } + + :local JobCount [ :len [ / system script job find where script=$Script ] ]; + + :if ($JobCount = 0) do={ + $LogPrintExit2 error $0 ("No script '" . $Script . "' is running!") true; + } + + :if ([ :len ($ScriptLockOrder->$Script) ] > $JobCount) do={ + $LogPrintExit2 error $0 ("More tickets than running scripts '" . $Script . "', resetting!") false; + :set ($ScriptLockOrder->$Script); + / system script job remove [ find where script=$Script ]; + } + + :local MyTicket [ $GetRandom20CharHex ]; + :set ($ScriptLockOrder->$Script) [ $AddTicket ($ScriptLockOrder->$Script) $MyTicket ]; - :if ([ :len [ / system script job find where script=$Script ] ] > 1) do={ - $LogPrintExit2 info $0 ("Script " . $Script . " started more than once... Aborting.") true; + :local WaitCount 0; + :while ($WaitMax > $WaitCount && (($ScriptLockOrder->$Script->0) != $MyTicket || [ :len ($ScriptLockOrder->$Script) ] < $JobCount)) do={ + :delay 100ms; + :set WaitCount ($WaitCount + 1); + :set JobCount [ :len [ / system script job find where script=$Script ] ]; + } + + :if ([ :len ($ScriptLockOrder->$Script) ] = $JobCount && ($ScriptLockOrder->$Script->0) = $MyTicket) do={ + :set ($ScriptLockOrder->$Script) [ $RemoveTicket ($ScriptLockOrder->$Script) $MyTicket ]; + :return false; } + + :set ($ScriptLockOrder->$Script) [ $RemoveTicket ($ScriptLockOrder->$Script) $MyTicket ]; + $LogPrintExit2 info $0 ("Script '" . $Script . "' started more than once" . [ $IfThenElse ($WaitCount > 0) \ + " and timed out waiting for lock" "" ] . "... Aborting.") [ $IfThenElse ($DoReturn = true) false true ]; + :return true; } # send notification via e-mail - expects at lease two string arguments |