I thought I would update everyone with where things stand with
the Tops-20 finger server.
Johnny and I agreed that, by default, the response to a DECnet
finger query is a sequences of records, each no longer than 132
bytes (more typically 90), terminated by a line-feed. If the
remote finger client or operating system can handle larger
buffers, then it can connect with optional data=STREAM.
Tops-20 will then dump everything in one giant record. Only the
Tops-20 finger client can handle this, although I suspect maybe a
VAX client might also be able to do it.
I had been making steady progress until I started stress testing
it, meaning having a session active on MIM::,
TOMMYT::, and VENTI2::
(local), each having a finger command in ready to go and then
pushing carriage return on all three as simultaneously as
possible.
This started generating errors on MIM::
that the "object wasn't available". What was going on was that
the structure of the Tops-20 finger server really wasn't
architected to have real time response for that much curiosity.
It only opens a single SRV:117
(finger) object at a time, waits for a connection, reads the data,
hands it off to an idle finger client fork via a pipe, and then
gets a new SRV:117 object.
In other words, it isn't until the finger client is started with
the connection redirected to DECnet that the server is ready to
accept another connection. That has what I would consider to be
noticeable latency, particularly on failure. An error doesn't
really matter for SMTP as it is a background task and just tries
again, later. An interactive finger on the other hand, has a user
sitting there waiting for a response, so it seemed to me that this
wasn't really going to cut it.
I took the model of the Tops-20 FAL
server, which has a single control fork, looking for illness in
sub-forks, all of which open their own FAL server object. The new
finger controller now starts separate FNGSRV
sub-server forks, creating a FINGER
sub-fork for each, gets all the communications lined up, and
starts all the FNGSRV sub-forks to
listen for connections.
This has the advantage of not clobbering the system on FNGSRV startup because resources are
gotten or creating sequentially, so there isn't much for a FNGSRV sub-fork to do except wait for a
connection and manage its own single FINGER
sub-fork.
Startup resource allocation looks like this:
[Fork FNGSRV opening
PIP:1;RECORD-LENGTH:200 for writing]
[Fork FNGSRV opening PIP:1.1 for reading]
[Fork FNGSRV opening SRV:117 for reading, writing]
[Fork FNGSRV opening PIP:2;RECORD-LENGTH:200 for writing]
[Fork FNGSRV opening PIP:2.2 for reading]
[Fork FNGSRV opening SRV:117 for reading, writing]
[Fork FNGSRV opening PIP:3;RECORD-LENGTH:200 for writing]
[Fork FNGSRV opening PIP:3.3 for reading]
[Fork FNGSRV opening SRV:117 for reading, writing]
The resulting JFN's being:
JFN File
Mode Bytes(Size)
2 FNGSRV.EXE.330 Read, Execute
3 FINGER.EXE.116 Read, Execute
15 PIP:1;RECORD-LENGTH:200 Append 0.(8)
16 PIP:1.1 Read 0.(8)
17 SRV:117 Read, Append 0.(8)
20 PIP:2;RECORD-LENGTH:200 Append 0.(8)
21 PIP:2.2 Read 0.(8)
22 SRV:117 Read, Append 0.(8)
23 PIP:3;RECORD-LENGTH:200 Append 0.(8)
24 PIP:3.3 Read 0.(8)
25 SRV:117 Read, Append 0.(8)
The resulting fork structure is:
=> FNGSRV (2): HALT at STARTS+13,
0.02719
Fork 12: HALT at 0, 0.00018
Fork 13: HALT at 0, 0.00016
Fork 10: HALT at 0, 0.00012
Fork 11: HALT at 0, 0.00012
Fork 6: HALT at 0, 0.00008
Fork 7: HALT at 0, 0.00007
So fork 2 is the finger server controller, forks 12, 10, and 6 are
finger server sub-forks, and forks 13, 11, and 7 are the
respective Tops-20 finger clients. Times are in tens of
microseconds, the maximum resolution that Tops-20 supports. What
can be seen is that fork creation is happening in sub-millisecond
time. This was not the case in the 1980's with KL10's (I think),
and modifications were necessary to Tops-20 and the EXEC to
capture the increased resolution.
I guess I'll have another version ready in about two weeks.