MOO-cows Mailing List Archive

[Prev][Next][Index][Thread]

Release 1.7.9 of the LambdaMOO server



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