Top Mud Sites Forum Return to TopMudSites.com
Go Back   Top Mud Sites Forum > Mud Development and Administration > MUD Coding
Click here to Register

Reply
 
Thread Tools
Old 10-15-2003, 10:48 PM   #1
erdos
 
Posts: n/a
Many modern codebases are set up so if the MUD crashes, it will automatically reboot without an admin having to go into the shell.  However, the same is not true of infinite loops.  When these crop up, you're sh!t out of luck until a very high admin comes along and kills it in the shell.  But there is a possible alternative.
The basic strategy is to have numerous instances of the MUD running simultaneously;  however, all except the main instance are lying low and waiting for a cue before even going into the basic bootup routine (and thus they take no significant RAM).
Meanwhile, the main mud is set up slightly differently than usual with regard to socket handling.  Rather than the master socket being told to listen once, and left there until the MUD shuts down, the master is periodically told to listen, wait briefly, accept ALL connections (which would require some looping and multiple pollings) (actually you'd want to limit the number of connections, if more than 50 connections are pending in a single instant it's probably someone trying to crash you), then after putting those connections on a different port, the master socket is unbound and turned off, to await the next polling.
Now, the other instances which have not yet been fully activated all connect to the main mud on a separate port (since it's all on the same computer you could use a firewall to prevent players from getting to that port), and merely occasionally "ping" the main mud to make sure it's still up.  As long as this is the case, all goes smoothly.  (If the connection goes down, it means the main mud merely crashed, as opposed to infinite looping.. in this case the main mud should be coming back up anyway shortly so just try to reestablish communications)
But when the main mud goes into an infinite loop, it stops responding to the lesser mud instances.  After a given period of time, the next mud instance realizes the main one is stuck, and so it sends out signals to all the others, letting them know that now IT is the main mud, and proceeds to boot itself up and begin listening for connections to the playport.  It also sends a signal to the suspiciously unresponsive instance notifying it that it is no longer in charge- so that in the rare event it's not a real infinite loop but just some massive (multiple minute long) lag, when the lag finally stops the old main mud will quietly shut itself down and let the new main mud continue being in charge.
There are, of course, alot of issues to work out, and I myself (being employed full time AND in college full time) have no time for coding myself these days.  Thus this is all untested, it was merely an idea that came to me the other day.  Once a true coder, you will thenceforth never cease to periodically recieve coding inspirations, long after retiring.
  Reply With Quote
Old 10-16-2003, 12:21 AM   #2
the_logos
Moderator
 
the_logos's Avatar
 
Join Date: Sep 2002
Location: Mill Valley, California
Posts: 2,301
the_logos will become famous soon enough
Rapture automatically catches infinite loops. If it doesn't get around to being able to process any player-input for X seconds it will skip the problem and kick up an error for review later. The time-period before it exits the infinite loop is settable by a user so, for instance, we give the daily backups a lot more leeway than most of the player verbs and regular game tasks and such.

--matt
the_logos is offline   Reply With Quote
Old 10-28-2003, 12:08 PM   #3
Kylotan
Member
 
Join Date: Jun 2003
Location: Nottingham, UK
Home MUD: Abattoir (Smaug)
Home MUD: ex-Jellybean (Smaug)
Home MUD: ex-Dark Chambers (Merc)
Posts: 174
Kylotan is on a distinguished road
Send a message via ICQ to Kylotan Send a message via AIM to Kylotan Send a message via MSN to Kylotan Send a message via Yahoo to Kylotan
Quote:
Originally Posted by (erdos @ Oct. 15 2003,21:48)
Many modern codebases are set up so if the MUD crashes, it will automatically reboot without an admin having to go into the shell.  However, the same is not true of infinite loops.  When these crop up, you're sh!t out of luck until a very high admin comes along and kills it in the shell.
Not true; Smaug demonstrates how it's possible to use the alarm signal to break out of potentially infinitely-long operations. Generally though, your infinite loops are only gonna be in scripts, and it should be easy enough to implement a way to monitor scripts and ensure they complete within a specified period of time.
Kylotan is offline   Reply With Quote
Old 10-28-2003, 04:13 PM   #4
Derk
New Member
 
Join Date: Oct 2003
Posts: 19
Derk is on a distinguished road
Basic process accounting, for a unix admin. There are runaway process catcher... they notice processes using 100% cpu and kill them...

The mud could restart when its killed.. easy.

Any situation where loops like that can happen is bad design in my opinion.. but whatever.
Derk is offline   Reply With Quote
Old 11-06-2003, 06:02 AM   #5
Kastagaar
Member
 
Join Date: Apr 2002
Location: Hampshire, UK
Posts: 117
Kastagaar is on a distinguished road
Send a message via Yahoo to Kastagaar
The most probable cause for infinite looping is, in my opinion, bad design. DikuMUDs in particular suffer from this because of their linked-list design. They use the idiom of "a data element in the list is a node in the list". Consider:

[code] a -> b -> c -> a[/quote]

We can see that iterating this is an infinite loop, because the node a points to the node b. Now consider using the "list node and data element are distinct" option:

[code]
node -> node -> node -> node
a b c a
[/quote]

(Eh? the code tag is not monospaced?)

Even though a is incorrectly in the list twice, there is no infinite loop when iterating over the list because the last node is still the last node.

This approach has its drawbacks, though: it takes more memory and probably more (although negligible) processor time when iterating. It also requires more memory management, because each node must be dynamically created.
Kastagaar is offline   Reply With Quote
Old 11-06-2003, 08:42 AM   #6
erdos
 
Posts: n/a
Quote:
Originally Posted by (Kastagaar @ Nov. 06 2003,05:02)
The most probable cause for infinite looping is, in my opinion, bad design.  DikuMUDs in particular suffer from this because of their linked-list design.  They use the idiom of "a data element in the list is a node in the list".  Consider:

[code] a -> b -> c -> a
[/quote]
Having coded on DIKU derivatives for years, I've never found that to be a problem. It takes only a smidgen of discipline to keep from linking the same thing to a list multiple times. Truly problematic infinite loops are usually a lot more convoluted. For example:
a player steps into a nofloor room and enters freefall, eventually landing, several rooms below, in a teleport room with 0 teleport delay that whisks them... right back where they started, to repeat the process.

With more cluttered codebases, codebases with tons and tons of features, it becomes ever more difficult for a coder to perceive all the possibilities. Often, an infinite loop requires the participation of a careless builder. There are diverse ways to make infinite loops with mob progs, despite coded attempts to reduce such risk.

If things are showing up twice in your linked lists, then infinite looping is the least of your worries! ;)
  Reply With Quote
Old 11-11-2003, 07:24 AM   #7
Kastagaar
Member
 
Join Date: Apr 2002
Location: Hampshire, UK
Posts: 117
Kastagaar is on a distinguished road
Send a message via Yahoo to Kastagaar
Quote:
Originally Posted by
Having coded on DIKU derivatives for years, I've never found (the data-element-is-a-node paradigm) to be a problem.
I actually speak from experience. One particularly hard-to-find bug was caused by people putting up their corpses ( ! ) for automatic auction, and not having them bought. Since the crash appeared a couple of minutes after the bug occurred, it was exceedingly hard to track down.

Not that I'm saying either implementation is strictly better, just that with the distinct list-node/object paradigm, the error is detectable at insertion time.
Kastagaar is offline   Reply With Quote
Old 11-11-2003, 09:40 PM   #8
Shanks
New Member
 
Join Date: Aug 2003
Location: Brisbane, Australia
Posts: 2
Shanks is on a distinguished road
On Ancient Anguish one doesn't have to worry quite so much about infinite loops, as the mud doesn't usually crash as a result. Ancient Anguish is based on Amylaar LPMud 3.2.1@141.

Consider the following object:

[code] #pragma strict_types
inherit "obj/treasure";

void create()
{
;;create();
set_short("a looper");
set_long("This is an object that performs an infinite loop with the loop comm
nd.");
set_name("looper");
}

void init()
{
;;init();

add_action("do_loop", "loop");
}

int do_loop(string what)
{
// INFINITE LOOP;
while (1)
;
}[/quote]

What happens when you invoke the loop command?

[code] > loop
Too long evaluation. Execution aborted.
program; w/shanks/looper.c, object; w/shanks/looper#69319 line 21[/quote]

-Shanks
Shanks is offline   Reply With Quote
Old 01-19-2004, 08:01 AM   #9
Samson
Member
 
Samson's Avatar
 
Join Date: Apr 2002
Location: United Socialist States of America
Home MUD: SmaugMuds.org
Home MUD: Arthmoor MUD Hosting
Posts: 249
Samson is on a distinguished road
If infinite loop protection is what you're after, as Kylotan suggested Smaug has a set_alarm function. Using that, the following little tidbits will do the trick:

Top of game_loop, with other signal stuff:

signal( SIGALRM, caught_alarm );

In game_loop, after the new_descriptor call:

set_alarm( 30 );

And again at the bottom of game_loop, to reset it ( not sure if this is needed ):

set_alarm( 0 );

The set_alarm function itself, which is just a wrapper:

[code]
void set_alarm( long seconds )
{
alarm( seconds );
}
[/quote]

And caught_alarm:

[code]
/*
* LAG alarm! -Thoric
*/
static void caught_alarm( int signum )
{
bug( 'ALARM CLOCK! In section %s', alarm_section );
echo_to_all( AT_IMMORT, 'Alas, the hideous malevalent entity known only as 'Lag' rises once more!', ECHOTAR_IMM );
if( newdesc )
{
FD_CLR( newdesc, &in_set );
FD_CLR( newdesc, &out_set );
FD_CLR( newdesc, &exc_set );
log_string( 'clearing newdesc' );
}

game_loop();

/* Clean up the loose ends. */
close_mud( );

/*
* That's all, folks.
*/
log_string( 'Normal termination of game.' );
log_string( 'Cleaning up Memory.&d' );
cleanup_memory();
exit( 0 );
}
[/quote]

I've tested this out with a deliberate infinite loop command, it caught it and was able to restart game_loop. Smaug does not handle this use of the alarm stock, I added that part, but they were already using it in new_descriptor to break up connection problems. So I figured why not?
Samson is offline   Reply With Quote
Reply


Thread Tools


Making your MUD less prone to infinite looping - Similar Threads
Thread Thread Starter Forum Replies Last Post
The making of a Mud lovechiefs Newbie Help 4 05-22-2007 07:44 PM
Making a new MUD Aeran Legal Issues 11 01-10-2007 04:30 PM
Pkillers! Come to Infinite Fear! Thlundar Advertising for Players 0 02-08-2005 12:36 AM
Infinite Fear wants YOU! Thlundar Advertising for Staff 1 01-12-2005 08:14 AM
Infinite Fear needs YOU! Thlundar Advertising for Players 1 01-12-2005 03:29 AM

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off

All times are GMT -4. The time now is 07:00 PM.


Powered by vBulletin® Version 3.6.7
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Style based on a design by Essilor
Copyright Top Mud Sites.com 2014