aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Christian Hesse <mail@eworm.de>2021-07-01 22:52:23 +0200
committerGravatar Christian Hesse <mail@eworm.de>2021-07-01 22:52:23 +0200
commit3f893a327d3892e5f29dacadc754b9999b91d097 (patch)
tree4e8adf326947aded9595bf68ff4a65b4d58cd667
parent89f8dc712001872783c8b3be7208bc1d726a12dd (diff)
parentaad91d90ea3c4cbe21b5c4f61fed94aaa337bddb (diff)
Merge branch 'ScriptLock' into next
-rw-r--r--global-functions61
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