MOO-cows Mailing List Archive
[Prev][Next][Index][Thread]
Release 1.7.9 of the LambdaMOO server
-
Date: Wed, 18 Oct 1995 10:42:18 PDT
-
From: Pavel Curtis <Pavel@parc.xerox.com>
-
Fake-Sender: pavel@parc.xerox.com
The bugs found during the alpha-test phase have been fixed and we've been
running on the new server successfully for some time now, so it would appear
worth doing a real release of version 1.7.9, recommended for use by all MOO
sites. The tar file is in the usual place:
ftp://ftp.parc.xerox.com/pub/MOO/LambdaMOO-1.7.9.tar.Z
Here's the ChangeLog.txt entries for both the alpha release and this one; be
sure to read all entries marked with the word `NOTE' *before* shutting down
your old server and upgrading.
Version 1.7.9alpha1, 25 September 1995
-- Fixed a few minor configuration and portability problems.
-- Fixed a potentially server-crashing bug in subrange assignments.
-- Renamed the internal server function `log()', to avoid name conflicts with
the logarithm function in the math library.
-- Changed the name-lookup subsystem to be more optimistic about the chances of
eventually recovering from an earlier failure to restart the lookup process.
Also bullet-proofed it against problems with its read() calls getting
interrupted by the checkpoint timer.
-- Added a paragraph to `README' explaining how to boost the limit on the
number of connections a server can support.
-- Added two new built-in functions enabling faster case-sensitive tests:
equal(X, Y) returns true iff the values X and Y are completely equal,
including the case of any strings they might contain; this is just
a case-sensitive version of the `==' expression.
is_member(X, L) is a similarly case-sensitive version of `X in L'.
-- Made the `.program' built-in command wiz-only if
$server_options.protect_set_verb_code exists and is true.
-- Added the built-in function `set_connection_option(CONN, OPTION, VALUE)',
for controlling various optional behaviors on the connection CONN. The only
allowed values for OPTION in this release are as follows:
"hold-input" -- if VALUE is true, then input received on CONN will
never be treated as a command; instead, it will remain in the queue
until retrieved by a call to read().
"client-echo" -- (NP_TCP configurations only) sends the Telnet Protocol
WON'T ECHO or WILL ECHO commands (depending on whether VALUE is
true or false, respectively). For clients that support the Telnet
Protocol, this should toggle whether or not the client echoes
locally the characters typed by the user. Note that the server
never echoes input characters under any circumstances.
-- Fixed stupid bug that let people lose by setting $server_options.fg_ticks
and company to negative values.
-- Added an optional second argument to the `read()' built-in function. If it
is provided and true, then this call to `read()' will not suspend the
calling task under any circumstances. If there is input currently
available, it will be returned immediately; otherwise, `read()' returns 0.
(As before, if no input is available and no more is coming, `read()' raises
E_INVARG as an end-of-input indicator.)
-- Added flow-control to the server's input-handling: if more than a reasonable
amount of unprocessed input accumulates for any connection, the server will
temporarily stop trying to read from that connection at all, until the
backlog drops down substantially.
-- Fixed a longstanding bug in match() that could make it return garbage in
certain circumstances. More bugs in match() almost certainly still exist.
(Thanks to Judy Anderson for finding this.)
-- Fixed a minor memory leak in the case where #0:do_command() exists and
returns a list or string value. (Thanks to Ian Macintosh for finding this.)
-- Fixed a possible race condition in the TCP networking code, where a timer
could go off before we've installed the exception handler. (Thanks to Alex
Stewart for finding this.)
-- Officially deprecated the USE_GNU_MALLOC option in options.h, since it's not
aging very well.
-- Completely replaced the regular-expression matching implementation that
underlies match() and rmatch(); it used to be the GNU `regex' package and is
now the GNU `RX' package shipped with GNU `sed'. This may not eliminate all
bugs in match(), but it almost certainly has moved them around a bit.
********** The old GNU regex package had a bug in its handling of certain
** NOTE ** patterns with parentheses in them, and it is reasonably likely
********** that many MOO programmers have, perhaps unconsciously, come to
depend upon this buggy behavior. Unfortunately for such programmers, RX
does not have this bug, so you will want to fix your regular expressions
before upgrading to this release; the fixed patterns will work correctly on
both releases.
The old bug concerns patterns of the form `%( ... %)*', that is, a starred
parenthesized sub-pattern; for example, consider the MOO expression
match("foo", "%(o%)*")
Using the old regex package, this returns
{2, 3, {{2, 3}, {0, -1}, ...}, "foo"}
which is *wrong*; the last successful match of the parenthesized sub-pattern
covered just the third character, not the second and third ones. Using the
new RX package, this expression returns the proper value:
{2, 3, {{3, 3}, {0, -1}, ...}, "foo"}
To get the effect of the old bug, you need another set of parentheses around
the whole starred sub-pattern:
match("foo", "%(%(o%)*%)")
Under both GNU regex and RX, if M is the result of this expression, we have
M[3][1] == {2, 3}
You should look carefully at your uses of match() and rmatch() before
upgrading to this release, fixing those places where your code depends on
the old, buggy behavior.
-- Added an optional third argument to the built-in function notify(); if it is
provided and true, and if there isn't enough room left in the given user's
output buffer to hold the given line, then notify() will return false and
the line will not have been queued for output. In all other circumstances,
notify() now returns true. If the new optional argument is false or not
provided, then the old behavior is invoked, in which some of the
already-queued output is discarded to make room for the new line.
-- Made it possible to change the maximum verb-call depth from inside the DB.
The MAX_VERB_DEPTH constant in options.h was replaced by
DEFAULT_MAX_STACK_DEPTH, which can be overridden by
$server_options.max_stack_depth. The maximum stack depth for any task is
set at the time that task is created and cannot be changed thereafter. This
implies that suspended tasks, even after being saved in and restored from
the DB, are not affected by later changes to
$server_options.max_stack_depth.
-- The task scheduler is now guaranteed never to assign a task_id() of zero.
-- The built-in functions notify(), connected_players(), connected_seconds(),
idle_seconds(), connection_name(), and set_connection_option() now treat
connections on which boot_player() has been called as if they did not exist.
-- A number of the messages printed to a connection by the server under various
circumstances can now be customized or eliminated from within the DB. In
each case, a property on $server_options is checked at the time the message
would be printed. If the property does not exist, the standard message is
printed. If the property exists and its value is not a string, then no
message is printed at all. Otherwise, the string is printed in place of the
standard message. The following list covers all of the newly customizable
messages, showing for each the name of the relevant property on
$server_options, the default/standard message, and the circumstances under
which the message is printed:
timeout_msg "*** Timed-out waiting for login. ***"
This in-bound network connection was idle and un-logged-in for
at least CONNECT_TIMEOUT seconds (as defined in options.h).
recycle_msg "*** Recycled ***"
The logged-in user of this connection has been recycled.
boot_msg "*** Disconnected ***"
The function boot_player() was called on this connection.
redirect_from_msg "*** Redirecting connection to new port ***"
The logged-in user of this connection has just logged in on
some other connection.
redirect_to_msg "*** Redirecting old connection to this port ***"
The user who just logged in on this connection was already
logged in on some other connection.
create_msg "*** Created ***"
The user object that just logged in on this connection did not
exist before #0:do_login_command() was called.
connect_msg "*** Connected ***"
The user object that just logged in on this connection existed
before #0:do_login_command() was called.
-- The `for VAR in [EXPR..EXPR]' looping construct can now be used with either
numbers or object numbers. That is, the construct `for o in [#0..#100]' is
now legal and does the obvious thing. NOTE that in the example `o' will
take on each of 101 object numbers in the specified range, regardless of
whether or not those object numbers are valid.
-- By popular request, added the built-in function `value_bytes(VALUE)', which
returns the number of bytes of memory required to store the given value. [I
was also asked to provide an `object_bytes(OBJ)' function, to give the total
memory required to store the given valid object, but I wanted to think
longer about possible interactions with 1.8.0's new modularity wall between
the DB implementation and the rest of the server.]
-- At long last, there is a DB-settable limit on the number of queued tasks any
single user can have at once. If $server_utils.user_task_limit exists and
is a non-negative number, then that is the `task limit' for normal users;
otherwise, the task limit is infinite. For wizards, the task limit is
controlled similarly by $server_utils.wizard_task_limit. Whenever a `fork'
statement or `suspend()' call are executed, the server checks whether or not
the current verb's owner (really, the current task perms) is already at or
above their task limit; if so, E_QUOTA is raised instead of either forking
or suspending. Reading tasks are not affected by the task limit.
-- The result of `tostr(E_QUOTA)' has been changed to the string
"Resource limit exceeded".
-- Applied Alex Stewart's pAS4 patch, which modifies the result of the
built-in function `connection_name()' on TCP networking configurations to
contain the remote port of the connection as well as the host name, in the
following format:
"99 from FOO.BAR.COM, port 9999"
As before, the first number in the result is pretty useless to MOO
programmers (it's the server's file descriptor for the connection) but can,
believe it or not, occasionally be useful to the maintainer.
******** Before upgrading an existing MOO to use this version of the server,
* NOTE * you should modify the verb $string_utils:connection_hostname_bsd as
******** follows:
@chmod $string_utils:connection_hostname_bsd -d
@program $string_utils:connection_hostname_bsd
s = args[1];
return strsub($string_utils:explode(s)[3], ",", "") || "";
.
This code should work compatibly with either version of the server.
-- Applied the key part of Alex Stewart's pAS7 patch, which fixes a problem
with the server occasionally hanging under Sun's Solaris 2.X system. [I
just removed the (useless) call to `shutdown()'; the SO_LINGER setting
didn't seem necessary or very useful.]
-- Added a new item to options.h, UNFORKED_CHECKPOINTS (off by default), that
prevents the server from forking a separate process to make checkpoints;
instead, the main server process performs the checkpoints itself, halting
all user interaction and MOO task execution for the duration.
-- Made the server's log output during the initial database load *slightly*
easier to understand.
-- Removed perhaps the last hard limit in the server; you can now have input
lines with more than 500 words on them. (Thanks to Bill Drury for sending
the message to MOO-Cows that finally got me to fix this longstanding bug.)
-- Disallowed empty verb names and those made up only of spaces.
-- Added a new built-in function `toliteral(VALUE)' such that
eval("return " + toliteral(VALUE) + ";") == {1, VALUE}
for all MOO values.
-- The `create()' built-in function will now create children of #-1.
-- Added an `emergency wizard mode' to the server's start-up sequence; if you
give an initial `-e' option on the command line, then after loading in the
database but *before* running #0:server_started(), the server will use its
standard input and output streams to allow execution of wizardly `eval'
commands and re-programming of verbs. For more details, type `help' from
inside the mode.
-- The verbs #0:user_disconnected() and #0:user_client_disconnected() are now
called for un-logged-in and outbound connections, too, just as they are for
logged-in ones.
******** Before upgrading an existing MOO to use this version of the server,
* NOTE * you should check your versions of these verbs to ensure that they
******** will work appropriately when passed negative (and therefore
invalid) object numbers. In most cases, it is probably sufficient to add
the following lines to the top of these verbs:
if (args[1] < #0)
return;
endif
This code should work compatibly with either version of the server, since
these verbs weren't being called with such object numbers before.
-- The server now saves, in the DB file, a list of all users with active
connections at the time of the checkpoint, shutdown, or panic that made the
file. Upon server start-up, if such a list is present in the DB file, a
call is made to #0:user_disconnected() for each formerly active connection.
These calls are made *before* the call to #0:server_started(). In this way,
there are no longer any discontinuities across a server reboot; from the
point of view of code in the DB, the only evidence of a reboot is that,
first, a relatively long time has passed since the last task execution,
second, all connections to the server (in-bound or out, logged-in or not)
have simultaneously been closed, and third, #0:server_started() has been
called by the server.
-- Fixed RX to do reverse-searching properly, so now rmatch() works again.
Also added a abort-check in the searching inner loop for the MOO interpreter
having run out of seconds.
Version 1.7.9, 18 October 1995
-- Fixed stupid bug in registration of toliteral(); it now shouln't raise
E_TYPE on all calls...
-- Added new built-in function `queue_info([USER])'. If USER is omitted,
returns a list of object numbers naming all users that currently have task
queues inside the server; if USER is provided, returns the number of tasks
currently queued for that user. It is guaranteed that queue_info(X) will
return zero for any X not in the result of queue_info(). In essence,
queue_info(X) is a very efficient version of
set_task_perms(X);
return length(queued_tasks());
In particular, it (a) doesn't have to allocate a large list structure, and
(b) tells you when passed no arguments the complete set of users for whom
there might actually be any queued tasks.
-- Fixed initialization bug in code to track number of queued tasks.
-- Liberalized the rules for when a call to read() without arguments will
succeed. Wizards won't get E_PERM if the current task is the one that was
last spawned by a command from the connection in question. You can assure
this in a number of ways:
1) Never suspend, but rather only call read(). This is the one way
that used to work.
2) Get lucky, go ahead and call suspend(), and have it just happen that
no commands have been read since the last time you called read(),
perhaps because the user was waiting for a prompt and no typing
ahead. This technique is *not* recommended.
3) Before suspending, call
set_connection_option(player, "hold-input", 1)
thereby ensuring that no commands will be taken from this player's
queue until you call
set_connection_option(player, "hold-input", 0)
This new third technique, suggested by Alex Stewart, was the impetus for
making this change.
-- Fixed a memory leak in the server's use of the new matcher.
-- Fixed a bug whereby the third element of a successful result of match() or
rmatch() contained 29 elements instead of the usual 9.
-- Changed the method for determining a given user's queued-task limit, which
is checked on every `fork' or `suspend()' from code running with that user's
permissions. If the current task perms are valid, and that object has a
`queued_task_limit' property, and the value of that property is a
non-negative number, then that number is the limit. Otherwise, if
$server_options.queued_task_limit exists and its value is a non-negative
number, then that's the limit. Otherwise, there is no limit. (Thanks to
Gustavo Glusman for his suggestion on how to do this.)
-- The following release note, given for the 1.7.9alpha1 release, contained an
error; the following version corrects it.
********** The old GNU regex package had a bug in its handling of certain
** NOTE ** patterns with parentheses in them, and it is reasonably likely
********** that many MOO programmers have, perhaps unconsciously, come to
depend upon this buggy behavior. Unfortunately for such programmers, RX
does not have this bug, so you will want to fix your regular expressions
before upgrading to this release; the fixed patterns will work correctly on
both releases.
The old bug concerns patterns of the form `%( ... %)*', that is, a starred
or plussed parenthesized sub-pattern; for example, consider the MOO
expression
match("foo", "%(o%)+")
Using the old regex package, this returns
{2, 3, {{2, 3}, {0, -1}, ...}, "foo"}
which is *wrong*; the last successful match of the parenthesized sub-pattern
covered just the third character, not the second and third ones. Using the
new RX package, this expression returns the proper value:
{2, 3, {{3, 3}, {0, -1}, ...}, "foo"}
To get the effect of the old bug, you need another set of parentheses around
the whole starred sub-pattern:
match("foo", "%(%(o%)+%)")
Under both GNU regex and RX, if M is the result of this expression, we have
M[3][1] == {2, 3}
You should look carefully at your uses of match() and rmatch() before
upgrading to this release, fixing those places where your code depends on
the old, buggy behavior.
-- ********** There is a severe performance bug in the new matcher, causing it
** NOTE ** to run exponentially slowly in certain cases. Fortunately, these
********** cases are usually easy to work around. If you get an `out of
seconds' traceback inside a call to `match()' or `rmatch()' (which will be
accompanied by an error message in the log giving the pattern in use), you
should probably check first for an instance of this problem.
The problem concerns starred or plussed sub-patterns inside a starred or
plussed parenthesized pattern. For example, here is a perfectly reasonable
pattern matching MOO strings:
"\"%([^\"\\]+%|\\.%)*\""
(It matches double quotes around a sequence of either (a) a cluster of
characters that don't require escaping, or (b) a single escaped character.)
Note, however, that it contains a plussed sub-pattern inside of starred
parentheses, precisely the bad case for the new matcher. Fortunately, this
pattern can be altered slightly, removing the `+', without changing the
meaning:
"\"%([^\"\\]%|\\.%)*\""
This pattern does not cause problems for the new matcher. I don't know of
any problematical patterns in LambdaCore, but there is at least one in
JHCore, in $code_utils:safe_eval, where it uses this pattern:
"^%([^\"()=]+%|\"%([^\\\"]*%|\\.%)*\"%)*$"
^ ^ ^
There are three instances of the problem here, indicated by the up-arrows;
the first two of them can be removed without changing the meaning:
"^%([^\"()=]%|\"%([^\\\"]%|\\.%)*\"%)*$"
The third instance, in my testing, does not appear to cause any problems in
practice.
I am continuing my search for a better regexp implementation, but this one
has worked well enough for us in practice that I didn't feel it was worth
holding up the release for it.
Home |
Subject Index |
Thread Index