loopctl - Monitor and control running loops and threads
This module redefines Tcl's "for", "foreach", and "while" commands to allow both the gathering of statistics about each loop, and also to provide a mechanism to pause, cancel, and resume a particular loop.
If an interp is stuck in something other than one of the standard loops then you can also send asynchronous abort signals to a thread.
Returns a list of loop IDs -- one for each running loop in all virtual servers. The loop IDs are opaque handles which can be passed to loopctl_info for more information.
Returns a list of attributes for the given loop in array-get format. If the loop ID is invalid, for example the loop exited between the calls to loopctl_loops and loopctl_info, then an exception is raised.
The process-wide unique ID of this loop.
The unique ID of the thread in which the loop is running. The thread ID is the same opaque handle which is returned from ns_thread id and related commands, and the same as that appearing in the error log. The thread ID can be used with the loopctl_abort command.
An ns_time value when the loop began running.
Number of loop iterations completed.
One of running, paused or canceled. The default state is running, and the state changes as the loop is controlled by the loopctl_pause, loopctl_run and loopctl_cancel commands.
If the loopctl_eval command has been used to evaluate a command in the context of the running loop, then this is a list containing the command name and any args.
Evaluate the given script at the top of the loop on the next spin, before the loop body is evaluated. The body of the loop will only be evaluated if the return value of script is TCL_OK (i.e. not error, break or continue).
Use loopctl_eval to manipulate loop control variables to un-stick a stuck loop, or to debug loop errors by logging variable state.
At the top of the next spin of the loop, before the loop body is evaluated, halt execution. The thread containing the Tcl interpreter in which the loop is running will not run until the loopctl_run is issued.
Un-pause a paused loop. The loop will continue by evaluating the loop body.
Raise an error at the top of the next spin of the loop, before the loop body is evaluated. The error will propagate until it is caught.
Returns a list of thread IDs -- one for each thread in which the loopctl module has been loaded.
Send a signal to the given thread that an error should be raised. Tcl checks for signals after the body of every command is evaluated, so if the thread is stuck running the internals of a command and new commands do not get a chance to run, then the signal will not get processed by the Tcl interpreter. Otherwise, TCL_ERROR will be the return value of the next command to be processed, which will propagate until caught.
Use the control port to identify a stuck loop and fix it without restarting the server.
server1:nscp 1> foreach lid [loopctl_loops] {
array set loop [loopctl_info $lid]
lappend loops [list $loop(spins) $lid]
}
server1:nscp 2> set loops [lsort -integer -decreasing -index 0 $loops]
server1:nscp 3> join $loops \n
420001 cc
3 d0
17 d4
server1:nscp 4> loopctl_cancel cc