[Encore] Output capacity in lambdamoo: altering MAX_QUEUED_OUTPUT
Daniel Jung
jung at uib.no
Tue Jan 15 18:00:33 MST 2008
Hi there
Resume:
-------
I have a problem in output peformance, and I wonder if altering
(augmenting) MAX_QUEUED_OUTPUT in options.h could improve serving high
network activity, or if someone could help with other solutions to the
problem.
Background:
-----------
I am running a number of educational moos on a web server. These moos
are web-based (encore 5). Traditionally, the lambdamoo server creates
and keeps a telnet channel to the client, and prints out one line here
and one line there. Now since the moos are web based, the database
produces complete web pages and lets the server print all the lines to
the client (a web browser). In the last version of encore, even the chat
is HTML based, meaning instead of a line pushed to the client, the line
is written into a player property, and a complete page is produced which
contains the property's contents (chat output), and printed to the
client. This works very well.
But if I use a web object forcing a page on each participant's web frame
(online slide show), at the same time as they are notified of the change
in the chat frame, there are, say, 500 lines produced twice for each
participant. If there are 30 people connected, that makes 30,000 lines
to be delivered by the moo server at exactly the same time.
The in-moo web server channels everything through one verb ($httpd:get)
which checks for cookie, authenticates, breaks down the HTTP GET command
into pieces, translates them into moo commands, does in-moo access
checks and piles up the lines for complete HTML pages, pumping them to
the client (conn) line by line with the notify() routine. At the end,
the code goes
****************************************
for line in (result)
while (!notify(conn, line, 1) && conn in connected_players(1))
suspend(0);
endwhile
endfor
if (buffered_output_length(conn))
while (buffered_output_length(conn))
suspend(0);
endwhile
endif
return;
****************************************
The code before that does a lot of things, but there are many suspends
scattered about, so that should be taken care of.
Problem:
--------
It happens ever so often that heavy use of the server (many people
connected and doing the same thing, teachers showing heavy web objects
to everybody simultanously) leads the moo to stall. I'm not talking
about lag, but about stalling, and these lines above cast an E_QUOTA
error. The moo in itself seems to be stable (no real crash), but the
users are getting timeouts and tracebacks. This is very frustrating. Now
I am sure the web server the moo is running on could handle the
pressure, as it is a top notch box. But lambdamoo is still single
threaded and, uhm, old, and piles up all the output before bursting out
(no multipart, no push, no flush). The thing is that online seminars
with exactly the same course program, and commands, with, say, five
people, work marvelously. The code above in itself runs smoothly, but if
the verb is called 30-fold, there might be problems. However, the
E_QUOTA is not raised in the call to $httpd:get, but inside it, in the
notifying loop.
Environment:
------------
There is virtually nothing on the web server (box) but ten moos like
this, a modestly visited homepage, php and some mysql. So far, only one
of the moos is giving us this headache. We reduced the database from 300
MB to 100 MB by deleting old stuff (I know, still big; mainly chat
recordings and lectures), and I am checking for background services,
nothing there. The lag on $login uses to be zero (:sampled and
.current). The same goes for installations of the software on other
servers where I got feedback that the same behaviour (E_QUOTA) is
encountered. (I haven't verified if there are checkpoint dumps in the
"crash"-occurences; I should configure those to never happen during
online classes I guess.)
I know, lambdamoo was never build for that, it was designed to print out
the occasional line here and there, and that works like a charm. Our
students and teachers depend on our systems though, and we desperately
need to find a solution.
Ticks and seconds:
------------------
options.h gives me
#define DEFAULT_MAX_STACK_DEPTH 50
#define DEFAULT_FG_TICKS 60000
#define DEFAULT_BG_TICKS 30000
#define DEFAULT_FG_SECONDS 10
#define DEFAULT_BG_SECONDS 6
which is already augmented from the original. The in-db calls are
$command_utils:suspend_if_needed
if (this:running_out_of_time()) ... suspend(x) ...
$command_utils:running_out_of_time
return ticks_left() < this.max_ticks_left || seconds_left() <
this.max_seconds_left;
$command_utils.max_ticks_left = 4000
$command_utils.max_seconds_left = 2
Buffered output:
----------------
;buffered_output_length() gives me 65536 bytes. This is pretty standard
I guess, coming from options.h:
#define MAX_QUEUED_OUTPUT 65536
#define MAX_QUEUED_INPUT MAX_QUEUED_OUTPUT
#define DEFAULT_CONNECT_TIMEOUT 300
(I just notice that INPUT_QUEUE_TIMEOUT is NOT defined here...)
I have a feeling (but may be completely wrong) that augmenting
MAX_QUEUED_OUTPUT could help us. Again, the box this thing is running on
is a potent one and should be able to handle more pressure from the moo.
The ChangeLog doesn't say much about buffered_output_length() which is
not already in the db help; the options.h file doesn't give instructions
on if, how and why this could be changed; consulting, e.g.,
http://www.moo-cows.com/maillist/archives/message.cgi?310 didn't help me
much either.
So my questions are:
--------------------
(1) Has anyone altered and tested MAX_QUEUED_OUTPUT in options.h before,
and with which results?
(2) Is there, theoretically, something to be gained by augmenting the
value there?
(3) Should I rather be looking into the fork() builtin, since suspends
somehow fork?
(4) Are there any other suggestions which might help us?
Thanks a lot!
- Daniel
More information about the Encore
mailing list