[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are a small number of circumstances under which the server directly and specifically accesses a particular verb or property in the database. This section gives a complete list of such circumstances.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Many optional behaviors of the server can be controlled from within the
database by creating the property $server_options
(i.e., #0.server_options
), assigning as its value a valid object number,
and then defining various properties on that object.
At a number of times, the server
checks for whether the property $server_options
exists and has an object
number as its value. If so, then the server looks for a variety of other
properties on that $server_options
object and, if they exist, uses their
values to control how the server operates.
Note that for some options, you will need to call load_server_options()
in order for any changes in their values to take effect.
See the description of that function
for more information on this.
The specific properties searched for are each described in the appropriate section below, but here is a brief list of all of the relevant properties for ease of reference:
bg_seconds
The number of seconds allotted to background tasks.
bg_ticks
The number of ticks allotted to background tasks.
connect_timeout
The maximum number of seconds to allow an un-logged-in in-bound connection to remain open. (This option is listener-specific.)
default_flush_command
The initial setting of each new connection's flush command.
fg_seconds
The number of seconds allotted to foreground tasks.
fg_ticks
The number of ticks allotted to foreground tasks.
max_concat_catchable
Cause value size limit violations to raise an error instead of abort the task.
max_list_concat
The maximum size list value that may be constructed
max_string_concat
The maximum size string value that may be constructed
max_stack_depth
The maximum number of levels of nested verb calls.
name_lookup_timeout
The maximum number of seconds to wait for a network hostname/address lookup.
outbound_connect_timeout
The maximum number of seconds to wait for an outbound network connection to successfully open.
protect_property
Restrict reading of built-in property to wizards.
protect_function
Restrict use of built-in function to wizards.
queued_task_limit
The maximum number of tasks a player can have.
support_numeric_verbname_strings
Enables use of an obsolete verb-naming mechanism.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are a number of circumstances under which the server itself generates
messages on network connections. Most of these can be customized or even
eliminated from within the database. In each such case, a property on
$server_options
is checked at the time the message would be printed. If
the property does not exist, a default message is printed. If the property
exists and its value is not a string or a list containing strings, then no
message is printed at all. Otherwise, the string(s) are printed in place of
the default message, one string per line. None of these messages are ever
printed on an outbound network connection created by the function
open_network_connection()
.
The following list covers all of the customizable messages, showing for each
the name of the relevant property on $server_options
, the default
message, and the circumstances under which the message is printed:
boot_msg = "*** Disconnected ***"
The function boot_player()
was called on this connection.
connect_msg = "*** Connected ***"
The user object that just logged in on this connection existed before
$do_login_command()
was called.
create_msg = "*** Created ***"
The user object that just logged in on this connection did not exist before
$do_login_command()
was called.
recycle_msg = "*** Recycled ***"
The logged-in user of this connection has been recycled or renumbered (via the renumber() function).
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.
server_full_msg = {
"*** Sorry, but the server cannot accept any more connections right now.",
"*** Please try again later."}
This connection arrived when the server really couldn't accept any more connections, due to running out of a critical operating system resource.
timeout_msg = "*** Timed-out waiting for login. ***"
This in-bound network connection was idle and un-logged-in for too long.
The actual time limit is $server_options.connect_timeout
.
Fine point: If the network connection in question was received at a listening point (established by the ‘listen()’ function) handled by an object obj other than
#0
, then system messages for that connection are looked for onobj.server_options
; if that property does not exist, then the corresponding property on$server_options
is used instead. This also applies to theconnect_timeout
option.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The server maintains the entire MOO database in main memory, not on disk. It is therefore necessary for it to dump the database to disk if it is to persist beyond the lifetime of any particular server execution. The server is careful to dump the database just before shutting down, of course, but it is also prudent for it to do so at regular intervals, just in case something untoward happens.
To determine how often to make these checkpoints of the database, the
server consults the value of $dump_interval
. If it exists and its
value is an integer greater than or equal to 60, then it is taken as the number
of seconds to wait between checkpoints; otherwise, the server makes a new
checkpoint every 3600 seconds (one hour). If the value of
$dump_interval
implies that the next checkpoint should be scheduled at
a time after 3:14:07 a.m. on Tuesday, January 19, 2038, then the server instead
uses the default value of 3600 seconds in the future.
The decision about how long to wait between checkpoints is made again
immediately after each one begins. Thus, changes to $dump_interval
will take effect after the next checkpoint happens.
Whenever the server begins to make a checkpoint, it makes the following verb call:
$checkpoint_started() |
When the checkpointing process is complete, the server makes the following verb call:
$checkpoint_finished(success) |
where success is true if and only if the checkpoint was successfully written on the disk. Checkpointing can fail for a number of reasons, usually due to exhaustion of various operating system resources such as virtual memory or disk space. It is not an error if either of these verbs does not exist; the corresponding call is simply skipped.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When the server first accepts a new, incoming network connection, it is given
the low-level network address of computer on the other end. It immediately
attempts to convert this address into the human-readable host name that will be
entered in the server log and returned by the connection_name()
function. This conversion can, for the TCP/IP networking configurations,
involve a certain amount of communication with remote name servers, which can
take quite a long time and/or fail entirely. While the server is doing this
conversion, it is not doing anything else at all; in particular, it it not
responding to user commands or executing MOO tasks.
By default, the server will wait no more than 5 seconds for such a name lookup
to succeed; after that, it behaves as if the conversion had failed, using
instead a printable representation of the low-level address. If the property
name_lookup_timeout
exists on $server_options
and has an integer
as its value, that integer is used instead as the timeout interval.
When the open_network_connection()
function is used, the server must
again do a conversion, this time from the host name given as an argument into
the low-level address necessary for actually opening the connection. This
conversion is subject to the same timeout as in the in-bound case; if the
conversion does not succeed before the timeout expires, the connection attempt
is aborted and open_network_connection()
raises E_QUOTA
.
After a successful conversion, though, the server must still wait for the
actual connection to be accepted by the remote computer. As before, this can
take a long time during which the server is again doing nothing else. Also as
before, the server will by default wait no more than 5 seconds for the
connection attempt to succeed; if the timeout expires,
open_network_connection()
again raises E_QUOTA
. This default
timeout interval can also be overridden from within the database, by defining
the property outbound_connect_timeout
on $server_options
with an
integer as its value.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When a network connection is first made to the MOO, it is identified by a unique, negative object number. Such a connection is said to be un-logged-in and is not yet associated with any MOO player object.
Each line of input on an un-logged-in connection that is not a flush command
and is not consumed by out-of-band processing is parsed into words in
the usual way (see the chapter on command parsing for details) and then these
words are passed as the arguments in a call to the verb
$do_login_command()
. For example, the input line
connect Munchkin frebblebit |
would result in the following call being made:
$do_login_command("connect", "Munchkin", "frebblebit") |
In that call, the variable player
will have as its value the negative
object number associated with the appropriate network connection. The
functions notify()
and boot_player()
can be used with such object
numbers to send output to and disconnect un-logged-in connections. Also, the
variable argstr
will have as its value the unparsed command line as
received on the network connection.
If $do_login_command()
returns a valid player object and the connection
is still open, then the connection is considered to have logged into that
player. The server then makes one of the following verbs calls, depending on
the player object that was returned:
$user_created(player) $user_connected(player) $user_reconnected(player) |
The first of these is used if the returned object number is greater than the
value returned by the max_object()
function before
$do_login_command()
was invoked, that is, it is called if the returned
object appears to have been freshly created. If this is not the case, then one
of the other two verb calls is used. The $user_connected()
call is used
if there was no existing active connection for the returned player object.
Otherwise, the $user_reconnected()
call is used instead.
Fine point: If a user reconnects and the user's old and new connections are on two different listening points being handled by different objects (see the description of the
listen()
function for more details), thenuser_client_disconnected
is called for the old connection anduser_connected
for the new one.
If an in-bound network connection does not successfully log in within a certain
period of time, the server will automatically shut down the connection, thereby
freeing up the resources associated with maintaining it. Let L be the
object handling the listening point on which the connection was received (or
#0
if the connection came in on the initial listening point). To
discover the timeout period, the server checks on
L.server_options
or, if it doesn't exist, on
$server_options
for a connect_timeout
property. If one is found
and its value is a positive integer, then that's the number of seconds the
server will use for the timeout period. If the connect_timeout
property
exists but its value isn't a positive integer, then there is no timeout at
all. If the property doesn't exist, then the default timeout is 300 seconds.
When any network connection (even an un-logged-in or outbound one) is terminated, by either the server or the client, then one of the following two verb calls is made:
$user_disconnected(player) $user_client_disconnected(player) |
The first is used if the disconnection is due to actions taken by the server
(e.g., a use of the boot_player()
function or the un-logged-in timeout
described above) and the second if the disconnection was initiated by the
client side.
It is not an error if any of these five verbs do not exist; the corresponding call is simply skipped.
Note: Only one network connection can be controlling a given player object at a given time; should a second connection attempt to log in as that player, the first connection is unceremoniously closed (and
$user_reconnected()
called, as described above). This makes it easy to recover from various kinds of network problems that leave connections open but inaccessible.
When the network connection is first established, the null command is
automatically entered by the server, resulting in an initial call to
$do_login_command()
with no arguments. This signal can be used by the
verb to print out a welcome message, for example.
Warning: If there is no
$do_login_command()
verb defined, then lines of input from un-logged-in connections are simply discarded. Thus, it is necessary for any database to include a suitable definition for this verb.
Note that a database with a missing or broken $do_login_command
may still be accessed (and perhaps repaired) by running the server with
the -e
command line option. See section Emergency Wizard Mode.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
On any connection for which the connection-option disable-oob
has not been set,
any unflushed incoming lines that begin with the out-of-band prefix will be treated as out-of-band commands,
meaning that if the verb $do_out_of_band_command()
exists and is executable,
it will be called for each such line.
For more on this, see Out-of-band Processing.
As we previously described in The Built-in Command Parser, on any logged-in connection that
read()
call,
.program
command in progress, and
hold-input
set,
any incoming line that
.program
or one of the other four intrinsic commands
will result in a call to $do_command()
provided that verb exists and is executable.
If this verb suspends or returns a true value, then processing of that line ends at this point,
otherwise, whether the verb returned false or did not exist in the first place,
the remainder of the builtin parsing process is invoked.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Whenever the server is booted, there are a few tasks it runs right at the
beginning, before accepting connections or getting the value of
$dump_interval
to schedule the first checkpoint (see below for more
information on checkpoint scheduling).
First, the server calls $user_disconnected()
once for each user who
was connected at the time the database file was written; this allows for any
cleaning up that's usually done when users disconnect (e.g., moving their
player objects back to some `home' location, etc.).
Next, it checks for the existence of the verb $server_started()
. If
there is such a verb, then the server runs a task invoking that verb with no
arguments and with player
equal to #-1
. This is useful for
carefully scheduling checkpoints and for re-initializing any state that is not
properly represented in the database file (e.g., re-opening certain outbound
network connections, clearing out certain tables, etc.).
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As described earlier, in the section describing MOO tasks, the server places limits on the number of seconds for which any task may run continuously and the number of “ticks,” or low-level operations, any task may execute in one unbroken period. By default, foreground tasks may use 30,000 ticks and five seconds, and background tasks may use 15,000 ticks and three seconds.
The server also places a limit on the number of levels of nested verb calls,
raising E_MAXREC
from a verb-call expression if the limit is exceeded.
The limit is 50 levels by default.
In addition, the server limits the size of list and string values that may be constructed to 16,777,216 elements by default.
Finally, the server can limit the number of forked or suspended tasks a given programmer can have queued at a given time; by default there is no limit.
All of these limits can be overridden from within the database by defining
any or all of the following properties on $server_options
and giving
them integer values:
bg_seconds
The number of seconds allotted to background tasks.
bg_ticks
The number of ticks allotted to background tasks.
fg_seconds
The number of seconds allotted to foreground tasks.
fg_ticks
The number of ticks allotted to foreground tasks.
max_stack_depth
The maximum number of levels of nested verb calls.
max_list_concat
The maximum size list value that may be constructed
max_string_concat
The maximum size string value that may be constructed
queued_task_limit
The maximum number of tasks a player can have.
The server ignores the values of fg_ticks
and bg_ticks
if they
are less than 100 and similarly ignores fg_seconds
and bg_seconds
if their values are less than 1. A value of max_stack_depth
less
than 50 is likewise ignored. This may help prevent utter disaster should
you accidentally give these options uselessly-small values.
Recall that command tasks and server tasks are deemed foreground tasks, while forked, suspended, and reading tasks are defined as background tasks. The respective ticks and seconds limits take effect only at the beginning of execution or upon resumption of execution after suspending or reading. The maximum stack depth is set at the time that task is created and cannot be changed thereafter, even after being saved in and restored from the DB.
The limit on number of queued tasks is consulted upon attempts to execute a
fork
statement, a call to suspend()
, or a blocking call to
read
. If the programmer already has a number of queued tasks that is
greater than or equal to the limit, E_QUOTA
is raised instead. A
property on the programmer named queued_task_limit
that is set to a
non-negative integer takes precedence over $server_options.queued_task_limit
.
If both the programmer-specific and server properties are nonexistent or negative,
then there is no limit.
Limits on list and string sizes are not task-specific and may change at any
time, though these are amongst the options that require
load_server_options
in order to take effect. Attempting to create
an value of size beyond the limit immediately aborts the task in the same
manner as when the seconds limit is exceeded. This behavior can be changed by
setting $server_options.max_concat_catchable
to a true value,
in which case E_QUOTA
is raised instead.
The value size limits may be removed by setting max_list_concat
and/or
max_string_concat
to zero or negative values. Note that removing these
limits or setting them too large relative to the memory available on the server
host will cause the server to crash if an overly large value construction is
attempted.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The server will abort the execution of tasks for either of two reasons:
In each case, after aborting the task, the server attempts to call a particular handler verb within the database to allow code there to handle this mishap in some appropriate way. If this verb call suspends or returns a true value, then it is considered to have handled the situation completely and no further processing will be done by the server. On the other hand, if the handler verb does not exist, or if the call either returns a false value without suspending or itself is aborted, the server takes matters into its own hands.
First, an error message and a MOO verb-call stack traceback are printed to the player who typed the command that created the original aborted task, explaining why the task was aborted and where in the task the problem occurred. Then, if the call to the handler verb was itself aborted, a second error message and traceback are printed, describing that problem as well. Note that if the handler-verb call itself is aborted, no further `nested' handler calls are made; this policy prevents what might otherwise be quite a vicious little cycle.
The specific handler verb, and the set of arguments it is passed, differs for the two causes of aborted tasks.
If an error is raised and not caught, then the verb-call
$handle_uncaught_error(code, msg, value, traceback, formatted) |
is made, where code, msg, value, and traceback are the
values that would have been passed to a handler in a try
-except
statement and formatted is a list of strings being the lines of error and
traceback output that will be printed to the player if
$handle_uncaught_error
returns false without suspending.
If a task runs out of ticks or seconds, then the verb-call
$handle_task_timeout(resource, traceback, formatted) |
is made, where resource is the appropriate one of the strings
"ticks"
or "seconds"
, and traceback and formatted are
as above.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In the process of matching the direct and indirect object strings in a command
to actual objects, the server uses the value of the aliases
property, if
any, on each object in the contents of the player and the player's location.
For complete details, see the chapter on command parsing.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A built-in property prop is deemed protected if
$server_options.protect_prop
exists and has a true value.
However, no such property protections are recognized if the compilation option
IGNORE_PROP_PROTECTED
(see section Server Compilation Options) was set when building
the server. (It should be noted that enabling property protection
has significant performance costs).
Whenever verb code attempts to read (on any object) the value of a built-in
property that is protected in this way, the server raises E_PERM
if the
programmer is not a wizard.
A built-in function func()
is deemed protected if
$server_options.protect_func
exists and has a true value.
If, for a given protected built-in function, a corresponding verb
$bf_func()
exists and its ‘x’ bit is set, then that built-in
function is also considered overridden, meaning that any call to
func()
from any object other than #0
will be treated
as a call to $bf_func()
with the same arguments,
returning or raising whatever that verb returns or raises.
A call to a protected built-in function that is not overridden proceeds normally
as long as either the caller is #0
or has wizard permissions;
otherwise the server raises E_PERM
.
Note that you must call load_server_options()
in order to ensure that
changes made in $server_options
take effect.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Whenever the create()
function is used to create a new object, that
object's initialize
verb, if any, is called with no arguments. The call
is simply skipped if no such verb is defined on the object.
Symmetrically, just before the recycle()
function actually destroys an
object, the object's recycle
verb, if any, is called with no arguments.
Again, the call is simply skipped if no such verb is defined on the object.
Both create()
and recycle()
check for the existence of an
ownership_quota
property on the owner of the newly-created or -destroyed
object. If such a property exists and its value is an integer, then it is
treated as a quota on object ownership. Otherwise, the following two
paragraphs do not apply.
The create()
function checks whether or not the quota is positive; if
so, it is reduced by one and stored back into the ownership_quota
property on the owner. If the quota is zero or negative, the quota is
considered to be exhausted and create()
raises E_QUOTA
.
The recycle()
function increases the quota by one and stores it back
into the ownership_quota
property on the owner.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
During evaluation of a call to the move()
function, the server can make
calls on the accept
and enterfunc
verbs defined on the
destination of the move and on the exitfunc
verb defined on the source.
The rules and circumstances are somewhat complicated and are given in detail in
the description of the move()
function.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If the property $server_options.support_numeric_verbname_strings
exists
and has a true value, then the server supports a obsolete mechanism for less
ambiguously referring to specific verbs in various built-in functions. For
more details, see the discussion given just following the description of the
verbs()
function.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated by Roger Crew on March, 27 2010 using texi2html 1.78.