I have been playing around with stackless for a hobby project (MUD) and needed some advice with one particular problem I've encountered. Part of my goal was to see if it was possible to write scripts for a multi-player game in the same fashion that you would for a blocking, single-player game. Additionally, misbehaving scripts should timeout fairly quickly.

The basic MUD driver is written in C++ using boost.asio and stackless 3.2. Commands that come in usually create and schedule a new tasklet which calls the defined input handler in python. There is also a player.input() function which behaves like the normal blocking input, but actually just calls PyChannel_Receive on a connection-specific stackless channel in a C function and returns the result. If there is an input channel waiting, then any player input is sent there instead of creating a new tasklet.

In my event loop, I call PyStackless_RunWatchdog with a low instruction count to allow the rest of the event loop to continue without requiring cooperative scheduling inside the game scripts. If scripts run for X amount of time (clock time, rather than instruction count), I kill the tasklet. Otherwise, the tasklet is re-inserted and continues running. All of this actually works great, and allows things like the following:

class Player:
        def onConnect(self):
                # calls PyChannel_Receive(...)
                name = self.input("What is your name?")
                self.send("Welcome %s!" % name)

This part works just fine and as expected, even with many players connected. In addition, any infinite loop in normal code will be timed out, also as expected. All the timers fire properly as long as the watchdog is running as it should. However, the code that follows an input statement doesn't seem to be running under the watchdog at all. Infinite loops run infinitely, code never times out because the main event loop is blocked while the code is running - ie, if there were an infinite loop BEFORE the input statement above, the script be interrupted by the watchdog and killed after a second or two, but not if the loop came after the input statement.

I've browsed through some of the stackless code, and I'm not entirely sure what is happening in there. It appears to me that when data is received on a channel, it immediately fires off the rest of the function rather than scheduling it for execution? I may be entirely wrong here...

Has anyone encountered this at all? I'm happy to delve into and make changes to the stackless code if necessary, or if someone knows a better method to achieve the same thing I would appreciate any pointers. I would prefer to go under the assumption that script-writers do NOT know how stackless works and should not be required to do any cooperative scheduling themselves. Feel free to let me know if I was unclear on any particular points.

Thanks,
Dave Butler

_______________________________________________
Stackless mailing list
[email protected]
http://www.stackless.com/mailman/listinfo/stackless

Reply via email to