It all depends.

Attempts to connect a port or even to connect a super-server using potentially wrong password spoil Cache Audit with nasty records, so if they are done frequently those records can easilly overfill the Audit.

Several years ago I faced the similar problem in opposite direction: how to let load balancer recognize Cache instances which are no longer alive to remove them from its list. Load balancer was to distribute super-server connections as well as web based ones. The idea of polling 1972/tcp was dropped as soon as I recognized its impact on auditting. So I used a web app which allowed unauthenticated access for the simple reason that if 57772/tcp port had reasonably answered, 1972/tcp should be accessible as well. There were no firewall(s) between the load balancer and application servers, therefore I was sure that there were no external "forces" that could prevent them from answering. The solution was deployed on a couple of different load balancers and showed its robustness on a farm of 4-7 application servers and 1000-3000 concurrent users.

It's better to use CACHETEMP mapped global, e.g. ^CacheTempUserYourGlobal($job,...).

BTW there is another option: having a wrapper job, pass it an array serialized to JSON, other steps are evidient. I used it in one of my projects, and it was quicker than using of ^CacheTemp* intermediate global, while performance gain was not too sufficient (AFAIR)

The approach with a global is apparently easier, so I'd use it if performance would not of great importantance.

I remember well times when routines used to start with  KILL ^CacheTemp*($JOB)

Our developers do the same, but modern versions of OSs usually have 6 digit PIDs, so it may take several days till PIDs would re-cycle their numbers.

PPGs are used, however sometimes they are not applicable, e.g. when information is passed between processes via temp globals.

Clean-up is a good idea, but can be fully implemented when (and only when) all app classes use the same before-exit-processing code, i.e. the app is always finish through one exit point. Sometimes it's difficult to achieve, while it's worth to.

A while ago I thought about some enhancements of my purging task:

  • automatic detection of too quick growing globals
  • automatic detection of globals which belong to its scope, i.e. have @name@(PID) format.

 Maybe I do it when have some spare time... the priority of this work is rather medium.

Thank you, Timothy.
Definitely this is a solution, while our case is a bit more complex. It can be several running copies of "dangerous" utility started by different users, so we can't select the actual one neither by executable name nor by its window title as it is started with "-nogui" option and has got no window.

An approach how to bypass this limitation that we are going to implement looks like this:

 lock +^offPID
 set rc=$zf(-2,"drive:\path\utility --par1 --parN")
 if rc=0 {
   get PIDs of all running copies of utility.exe
   if '$data(^offPID(PID1)) {
       set ^offPID(PID1)=$h // search a new PID (let it be PID1)
       job checkJob(PID1)
   }
 } else {
   process an error
 }
 lock -^offPID
 ...
 ...

сheckJob(pPID) // check if pPID is running
  for {
    get PIDs of all running copies of utility.exe
    if pPID is not listed {
       kill ^offPID(pPID)
       quit
     
   } elseif timeout expired {
       set rc=$zf(-1,"taskkill /pid "_pPID)
       if rc=0 { ... }
       else { process an error }
       kill ^offPID(pPID)
       quit

   } else {
      hang 30 // wait...
   }
}
quit

Thank you, Robert.

In this case the PID saved in a file will be the PID of command processor (cmd) itself rather than the PID of an utility which it has invoked. If Cache process kill the cmd instance using this PID, the utility will continue its execution. Besides, there is no  parent-child relationship between the cmd and the utility, so /t switch (kill process tree) would not help.

Thank you, Stephen.

I should confess that you are quite write: our code resides in .cls, .inc, .int and also in globals. As to my straightforward code, it is not written yet. At the moment I have a simple "search-in-global engine", which matching ability should be improved (regexp?) and replacement functionality should be added. If speed will turn to be a problem, I will use it with ^ROUTINE, ^rINC and ^oddDEF globals as well, while I dislike this idea and prefer to start with official API (%Dictionary classes). 

If +value=value

This classic code is good for checking if the value is canonical number, while the term number can be interpreted in some other ways, e.g. a number in scientific format, double precision number, etc. Caché has a set of out-of-the-box functions to perform some of these checks, e.g. $isvalidnum, $isvaliddouble, $number, $normalize.

So, the answer depends on topic starter's conditions.

E.g., if I need to check if a number is a numlit (scientific numbers and numbers with starting zeroes are allowed), I'd use `$isvalidnum(x)`. Addition check on being integer (an intlit) can look like: `$isvalidnum(x)&&(+x\1=+x)`. Here are some testing results: 

USER> w !,?6,"Is number?",?20,"Is integer?",?35,"Is canonic?"
USER> for x="001a","002",0,1,"-1.2","+1.3","1E3" w !,x,?10," ",$isvalidnum(x),?20," ",$isvalidnum(x)&&(+x\1=+x),?35,x=+x
 
      Is number?    Is integer?    Is canonic?
001a       0         0             0
002        1         1             0
0          1         1             1
1          1         1             1
-1.2       1         0             1
+1.3       1         0             0
1E3        1         1             0

In other conditions I'd write another code. There is no universal answer to topic starter's question.

P.S. As to "Annotated MUMPS Standard" (http://71.174.62.16/Demo/AnnoStd):
An intlit is not necessarily a canonic representation of a number.

numlit is not necessarily a canonic representation of a number.

The reduction to a canonical numeric representation involves (colloquially) the removal of any redundant leading and trailing zeroes, the conversion of exponentionential notation to "mantissa only" notation, and the reduction of any leading plus (+) and minus (-) signs to at most one leading minus sign (see also Numeric interpretation of data).

Via SSH (putty, etc), am I right that you need to call csession <instance> to enter the Caché terminal? If so, there is no talk about SSH all. 

Caché has got embedded libssh2.dll/.so ages ago. Why not implement internal SSH server which can be a reasonable replacement for outdated (and Windows only) telnet one? It seems that some other projects (besides Web terminal) would take advantage from it.

Our customers are to check DB integrity on regular basis, usually weekly, while I don't remember a case when it showed errors which were not evidient without it (<DATABASE> errors in error and console logs, etc).

Last time when I had an opportunity to use ^REPAIR was about 1.5 year ago, when our support specialist defragmented free space in a database under Caché 2015.1.2. The bulletin from InterSystems about the possibility of defragmentation errors arrived a bit later... Thanks to backup performed before the defragmentation, the opportunity to use ^REPAIR was closed that time :) After upgrade to 2015.1.4 no errors of such kind were detected in the field.

The faults of Integrity check are:
- when there is some concurrent users' activity it may provide false positives in per database summary report (Errors found in database...) while there are no real errors neither in database nor in per global report;
- (mostly about TASKMGR): there is no way to include into the task completion reports (which can be e-mailed) any information from the task, e.g., about errors found by Integrity. 

Sergey, you are doing a great job popularizing our (unfairly) niche technology!

Despite the article was published on private resource,  such a phrase: 

They were first introduced in 1966 in the M(UMPS) programming language (which later evolved into Caché ObjectScript, COS), which was initially used in medical databases.

sounds (at least for me) as a disrespect to many talented people who contributed to the technology in terms of many other M implementations. Some of them already gone...

Truth should sound like this: COS was developed by InterSystems as a superset of M (see http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...). The  original language is still accepted by developers' community and alive in a few implementations. There are several signs of activity around the web: MUMPS Google group, user group (http://mumps.org/), effective ISO Standard (http://71.174.62.16/Demo/AnnoStd), etc.