Asynchronous Polling Limitation ?

Krusty (chad@mfst.com)
Mon, 23 Dec 1996 12:16:03 -0800

This is a scotty/tcl problem that I have:

BACKGROUND

The script that I have created performs asynchronous polling on a list
of nodes for a bunch of snmp data. It is intended to:

1) eliminate the need for running a seperate polling program for each
node
2) To allow polling requests to be sent out without having to wait for
the previous request's reply.

parameters for the script are:

the name of the MIB to be used
a filename of a file that contains a list of nodes to be polled
a filename of a file that contains a list of OIDs to be polled for each
node.
a filename of a file that contains a list of OID's and values to be used
to reset any counters.

The only method for performing asynchronous polling that I could come up
with was to perform a get with a callback. At the time that the get is
performed the ID for the request and what was asked for is stored in a
list. The callback returns the result and the request ID. Through
matching up what was asked for and what resulted the request can be
linked with the data. An 'snmp wait' is performed to ensure that all
results (good or bad) are returned before processing continues.

THE PROBLEM

The script works fine, however I have noticed that the performance
becomes very bad if more than 300 OID's are asked for (nodes x OID's).
I have varied all of the parameters that I could think of (i.e. lots of
nodes few OID's, few nodes many OID's)

I have tried various values for the window, number of nodes, number of
OID's, how many OID's asked for at a time and have always come up with
the limit of 300.

Exactly what happens is:

asking for 10 OID's takes x time to get and y time to sort
asking for 100 OID's takes 10x time to get and 10y time to sort
asking for 200 OID's takes 20x time to get and 20y time to sort
etc...etc..etc..
however
asking for 310 OID's takes 40x to get and 40y to sort
asking for 400 OID's takes 80x to get and 80y to sort.

A plot of the times vs OID's in all situations tried produces the same
result. The plot looks like a diode characteristic, or like a queueing
problem.

It appears to me that the script reaches some limitation in scotty or
TCL for the amount of events outstanding in the eventloop or the number
of requests that it can have outstanding.

The machine that I have this running on is a sparc 5 with 64MB ram (with
little else going on)

scotty 2.1.2 and tcl 7.5 are used.

Also I have noticed that if the window becomes too big many polls are
lost. I know that the window sets how many outstanding requests there
can be so I assume that the data is lost because more requests are sent
out than can be processed by the polled devices agent.

I have attached the code for any interested parties. Any comments,
suggestions or explanations would be appreciated.

Thanks

Chad Verbowski

THE CODE

These are the main parts. poll performs the async polling and newCorr
joins what was asked with what was returned...

###############################################################################
proc poll {thing } {

global miber slist cback rslt;

set nde [string range $thing 0 [expr [string first : $thing]-1]]
;
set slt [string range $thing [expr 1+[string first :
$thing]] [expr [string first . $thing]-1]];
set port [string range $thing [expr 1+[string first .
$thing]] [string length $thing]];
set rname [nslook $nde];
set hprt [string range $rname [expr 1+[string last .
$rname]] [string length $rname]];
set nprt [string range $rname 0 [string last . $rname]]
;
set node "$nprt[expr $hprt + $slt]";

####
set commun [getCommunity $node ];
set s [snmp session -window 20 -address $node -community $commun
-timeout 15];
lappend slist $s;
foreach key [array names miber] {
foreach elmt $miber($key) {
catch {set bb [$s get $elmt.$port {

lappend cback "%R::%V";}];lappend rslt
"$bb::$thing--$elmt";
}
}
}
}###########################################################################
#
#
proc newCorr { } {

global rinfo cback rslt;

#lsort $cback;
#lsort $rslt;
foreach thng $cback {
set mtch [string range $thng 0 [string first :: $thng]];
foreach prt $rslt {
if {[string first $mtch $prt] != -1 } {
set chnk [string range $prt [expr 2+ [string first :: $prt]] [string
length $prt]];
set answ [string range $thng [expr 2+ [string first :: $thng]] [string
length $thng]];
set rinfo($chnk) [chopup $answ];
# puts "$chnk - [chopup $answ]"
#puts "$n $k $e [chopup
$out($n.$k.$e)]";
break;
}
}
}
}
#########################################################################