Community discussions

MikroTik App
 
tdw
Forum Guru
Forum Guru
Topic Author
Posts: 1843
Joined: Sat May 05, 2018 11:55 am

on-up scripts, global variables and race conditions

Fri Sep 03, 2021 8:52 pm

Due to the permission limitations for commands run directly in on-up scripts, it is suggested that the on-up script action should just be to run a script which has been created in /system scripts (e.g. viewtopic.php?t=171750#p840220).

As it doesn't appear to be possible to pass arguments directly to scripts, when a script references the variables from the caller (e.g. $"caller-id", $user) are these specific to that invocation, or global in which case they may be changed by another on-up which occurs before the first has completed? i.e. what happens if another PPPoE client connects whilst the script for the original PPPoE connection has not yet completed execution.

Also, if using an array as a list which may have entries added and removed by more than one script, or script instance, are any operations atomic or is it possible the variable may be changed elsewhere part-way though a statement, e.g. when adding an item
:global things
:local item "somedata"
:set things ($things,$item)

or when removing an item
:global things
:local item ($things->0)
:set things [:pick $things 1 9999]


Any insights would be appreciated
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: on-up scripts, global variables and race conditions

Sat Sep 04, 2021 12:21 am

I do not see the problem:
on the on-up must be writed exactly, only, without any space, ";", quotes or "return", the name of the script (and not /system script run before)
the script must have dont-require-permissions, and all other permissions set.
All the parameters like $"caller-id", $user, etc. are usable LOCALLY inside the script, are not global.
If multiple instance are launched, each instance have it's own locally defined variables.

Working inside this script, except for circumventing restricted permission, is like exactly write inside the on-up field.
And each job are separate for another.
Obviously if you use :global variable inside one job, is shared among all jobs, but if happen, is your faut use "global" on useless way.
 
tdw
Forum Guru
Forum Guru
Topic Author
Posts: 1843
Joined: Sat May 05, 2018 11:55 am

Re: on-up scripts, global variables and race conditions

Mon Sep 06, 2021 3:51 pm

OK, so on-up=scriptName instantiates that script rather than calling it, and the session variables are local to the instance.

The documentation is not overly clear, and also leaves out other useful information such as the :typeof value "nothing" and the any operator:
> :local wibble;:put ([:typeof $wibble],[:len $wibble],(any $wibble))
nothing;0;false
> :local wibble [];:put ([:typeof $wibble],[:len $wibble],(any $wibble))
nil;0;false
> :local wibble [:toarray ""];:put ([:typeof $wibble],[:len $wibble],(any $wibble))
array;0;true
> :local wibble "";:put ([:typeof $wibble],[:len $wibble],(any $wibble))
str;0;true


Using global variables is neither a 'fault' nor 'useless', given that Mikrotik scripting has no primitives to handle lists or queues of objects (note this has nothing to do with address/interface lists or interface/simple queues).

In this case the object is to update a third-party system when a PPPoE connection is established, and given the inefficiencies of Mikrotik scripting / response time of the third-party system (the script can take several seconds to complete) I would like to have a small script which adds the PPPoE on-up session variables to a list, the main script then processes each list item sequentially. If there are a lot of new PPPoE sessions at the same time, for example resulting from a power cut affecting clients or a DFS event on a radio link, I don't particularly want dozens of instances of the script running at the same time.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11982
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: on-up scripts, global variables and race conditions

Mon Sep 06, 2021 4:06 pm

@tdw

I write exactly that, do not interpret as you want. (fixed grammar errors)
Obviously if you use :global variable within a job, it is shared among all jobs, but if it happen, it is your fault using "global" on useless way.

I've never written that using a :global variable outside to one shared script is an error or is useless.
 
tdw
Forum Guru
Forum Guru
Topic Author
Posts: 1843
Joined: Sat May 05, 2018 11:55 am

Re: on-up scripts, global variables and race conditions

Thu Sep 09, 2021 10:56 pm

For anyone with a similar use case... After some experimentation a global associative array works - the key is unimportant, it just has to be unique (to prevent collisions / data being overwritten) and increasing (to guarantee the earliest entries are processed first as arrays are sorted by key).

To add in on-up events:
:global connectionInfo
:if ([:typeof $connectionInfo] != "array") do={:set connectionInfo [:toarray ""]}
....
:set ($connectionInfo->$key) {mac=$"caller-id";ip=$"remote-address";user=$user}

To process and remove in a scheduled script:
:global connectionInfo
:if ([:typeof $connectionInfo] != "array") do={:set connectionInfo [:toarray ""]}
....
:local key
:local info
foreach key,info in=$connectionInfo do={
  :local mac ($info->"mac")
  :local ip ($info->"ip")
  :local user ($info->"user")
  ....
  :set ($connectionInfo->$key)
}

Who is online

Users browsing this forum: navigator and 22 guests