From 301ad4b3e570a362dd8f7b7fe4448d7638803509 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Sun, 27 Jun 2021 20:40:22 +0200 Subject: global-functions: $ScriptLock: allow to return... ... with true instead of breaking with error. --- global-functions | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/global-functions b/global-functions index 63c0e21..d15d176 100644 --- a/global-functions +++ b/global-functions @@ -904,13 +904,18 @@ # lock script against multiple invocation :set ScriptLock do={ - :global LogPrintExit2; + :local Script [ :tostr $1 ]; + :local DoReturn $2; - :local Script [ :tostr $1 ]; + :global IfThenElse; + :global LogPrintExit2; :if ([ :len [ / system script job find where script=$Script ] ] > 1) do={ - $LogPrintExit2 info $0 ("Script " . $Script . " started more than once... Aborting.") true; + $LogPrintExit2 info $0 ("Script " . $Script . " started more than once... Aborting.") \ + [ $IfThenElse ($DoReturn = true) false true ]; + :return true; } + :return false; } # send notification via e-mail - expects at lease two string arguments -- cgit v1.2.3-54-g00ecf From e13e3cfe34b2ac0c1ec859d05ba2d0df8adc2e0f Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Wed, 30 Jun 2021 21:10:58 +0200 Subject: global-functions: $ScriptLock: check if script exists --- global-functions | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/global-functions b/global-functions index d15d176..7b68701 100644 --- a/global-functions +++ b/global-functions @@ -910,6 +910,10 @@ :global IfThenElse; :global LogPrintExit2; + :if ([ :len [ / system script find where name=$Script ] ] = 0) do={ + $LogPrintExit2 error $0 ("A script named '" . $Script . "' does not exist!") true; + } + :if ([ :len [ / system script job find where script=$Script ] ] > 1) do={ $LogPrintExit2 info $0 ("Script " . $Script . " started more than once... Aborting.") \ [ $IfThenElse ($DoReturn = true) false true ]; -- cgit v1.2.3-54-g00ecf From b2d0ed1240e5ae5a0e48dfd706e8496e6492fd10 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Wed, 30 Jun 2021 21:18:38 +0200 Subject: global-functions: $ScriptLock: check if script is running --- global-functions | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/global-functions b/global-functions index 7b68701..255c30a 100644 --- a/global-functions +++ b/global-functions @@ -914,6 +914,10 @@ $LogPrintExit2 error $0 ("A script named '" . $Script . "' does not exist!") true; } + :if ([ :len [ / system script job find where script=$Script ] ] = 0) do={ + $LogPrintExit2 error $0 ("No script '" . $Script . "' is running!") true; + } + :if ([ :len [ / system script job find where script=$Script ] ] > 1) do={ $LogPrintExit2 info $0 ("Script " . $Script . " started more than once... Aborting.") \ [ $IfThenElse ($DoReturn = true) false true ]; -- cgit v1.2.3-54-g00ecf From 5d30886e597aa3ea0b5bc4ccbf7f62713df0de3d Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Sun, 27 Jun 2021 23:31:25 +0200 Subject: global-functions: $ScriptLock: rework with tickets Getting the order right is not easy... We use a global variable to store "tickets" in an array. Based on that scripts know their order. --- global-functions | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/global-functions b/global-functions index 255c30a..6c11258 100644 --- a/global-functions +++ b/global-functions @@ -907,23 +907,57 @@ :local Script [ :tostr $1 ]; :local DoReturn $2; + :global GetRandomNumber; :global IfThenElse; :global LogPrintExit2; + :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; } - :if ([ :len [ / system script job find where script=$Script ] ] = 0) do={ + :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 [ / system script job find where script=$Script ] ] > 1) do={ - $LogPrintExit2 info $0 ("Script " . $Script . " started more than once... Aborting.") \ - [ $IfThenElse ($DoReturn = true) false true ]; - :return 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 [ $GetRandomNumber ]; + :set ($ScriptLockOrder->$Script) [ $AddTicket ($ScriptLockOrder->$Script) $MyTicket ]; + + :if ([ :len ($ScriptLockOrder->$Script) ] = $JobCount && ($ScriptLockOrder->$Script->0) = $MyTicket) do={ + :set ($ScriptLockOrder->$Script) [ $RemoveTicket ($ScriptLockOrder->$Script) $MyTicket ]; + :return false; } - :return false; + + :set ($ScriptLockOrder->$Script) [ $RemoveTicket ($ScriptLockOrder->$Script) $MyTicket ]; + $LogPrintExit2 info $0 ("Script '" . $Script . "' started more than once... Aborting.") \ + [ $IfThenElse ($DoReturn = true) false true ]; + :return true; } # send notification via e-mail - expects at lease two string arguments -- cgit v1.2.3-54-g00ecf From 7de3457f449bcb37f39a12ea81e3c73cfb14e7ba Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Wed, 30 Jun 2021 21:27:39 +0200 Subject: global-functions: $ScriptLock: allow to wait for lock --- global-functions | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/global-functions b/global-functions index 6c11258..a19e44b 100644 --- a/global-functions +++ b/global-functions @@ -906,6 +906,7 @@ :set ScriptLock do={ :local Script [ :tostr $1 ]; :local DoReturn $2; + :local DoWait $3; :global GetRandomNumber; :global IfThenElse; @@ -949,6 +950,11 @@ :local MyTicket [ $GetRandomNumber ]; :set ($ScriptLockOrder->$Script) [ $AddTicket ($ScriptLockOrder->$Script) $MyTicket ]; + :while ($DoWait = true && (($ScriptLockOrder->$Script->0) != $MyTicket || [ :len ($ScriptLockOrder->$Script) ] < $JobCount)) do={ + :delay 100ms; + :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; -- cgit v1.2.3-54-g00ecf From 0b4c1861cf54a017bbe1e7cf6e0e91f4b63e9e73 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 1 Jul 2021 10:26:16 +0200 Subject: global-functions: $ScriptLock: use a limit on lock... ... to make sure it does not lock forever. --- global-functions | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/global-functions b/global-functions index a19e44b..9c4a53e 100644 --- a/global-functions +++ b/global-functions @@ -906,7 +906,7 @@ :set ScriptLock do={ :local Script [ :tostr $1 ]; :local DoReturn $2; - :local DoWait $3; + :local WaitMax ([ :tonum $3 ] * 10); :global GetRandomNumber; :global IfThenElse; @@ -950,8 +950,10 @@ :local MyTicket [ $GetRandomNumber ]; :set ($ScriptLockOrder->$Script) [ $AddTicket ($ScriptLockOrder->$Script) $MyTicket ]; - :while ($DoWait = true && (($ScriptLockOrder->$Script->0) != $MyTicket || [ :len ($ScriptLockOrder->$Script) ] < $JobCount)) do={ + :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 ] ]; } @@ -961,8 +963,8 @@ } :set ($ScriptLockOrder->$Script) [ $RemoveTicket ($ScriptLockOrder->$Script) $MyTicket ]; - $LogPrintExit2 info $0 ("Script '" . $Script . "' started more than once... Aborting.") \ - [ $IfThenElse ($DoReturn = true) false true ]; + $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; } -- cgit v1.2.3-54-g00ecf From aad91d90ea3c4cbe21b5c4f61fed94aaa337bddb Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 28 Jun 2021 01:13:31 +0200 Subject: global-functions: $ScriptLock: use hex string for ticket Does not matter what the ticket looks like, but using hex string it is not converted to number. --- global-functions | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global-functions b/global-functions index 9c4a53e..e7080e4 100644 --- a/global-functions +++ b/global-functions @@ -908,7 +908,7 @@ :local DoReturn $2; :local WaitMax ([ :tonum $3 ] * 10); - :global GetRandomNumber; + :global GetRandom20CharHex; :global IfThenElse; :global LogPrintExit2; @@ -947,7 +947,7 @@ / system script job remove [ find where script=$Script ]; } - :local MyTicket [ $GetRandomNumber ]; + :local MyTicket [ $GetRandom20CharHex ]; :set ($ScriptLockOrder->$Script) [ $AddTicket ($ScriptLockOrder->$Script) $MyTicket ]; :local WaitCount 0; -- cgit v1.2.3-54-g00ecf