Added utils.utils.run_async as a simple wrapper to the Twisted deferred system. This allows for easily making a long-time-running process or command asynchronous.

This commit is contained in:
Griatch 2010-10-21 20:15:11 +00:00
parent 547eb53b32
commit 31edce0ba1
2 changed files with 61 additions and 8 deletions

View file

@ -7,8 +7,7 @@ from django.conf import settings
from django.db import IntegrityError
from src.comms.models import Msg
from src.permissions import permissions
from src.utils import create
from src.utils import debug
from src.utils import create, debug, utils
from game.gamesrc.commands.default.muxcommand import MuxCommand
from src.commands import cmdsethandler
@ -29,17 +28,38 @@ class CmdTest(MuxCommand):
key = "@test"
aliases = ["@te", "@test all"]
permissions = "cmd:Immortals Wizards"
#permissions = "cmd:Immortals" #Wizards
# the muxcommand class itself handles the display
# so we just defer to it by not adding any function.
def func(self):
cmdsetname = "game.gamesrc.commands.default.cmdset_default.DefaultCmdSet"
self.caller.msg(cmdsethandler.CACHED_CMDSETS)
cmdsethandler.import_cmdset(cmdsetname, self, self)
self.caller.msg("Imported %s" % cmdsetname)
self.caller.msg(cmdsethandler.CACHED_CMDSETS)
def test():
li = []
for l in range(10000):
li.append(l)
self.caller.msg(li[-1])
return "This is the return text"
#print 1/0
def succ(f):
self.caller.msg("This is called after successful completion. Return value: %s" % f)
def err(e):
self.caller.msg("An error was encountered... %s" % e)
#self.caller.msg("printed before call to sync run ...")
#test()
#self.caller.msg("after after call to sync run...")
self.caller.msg("printed before call to async run ...")
utils.run_async(test, at_return=succ, at_err=err)
self.caller.msg("printed after call to async run ...")
#cmdsetname = "game.gamesrc.commands.default.cmdset_default.DefaultCmdSet"
#self.caller.msg(cmdsethandler.CACHED_CMDSETS)
#cmdsethandler.import_cmdset(cmdsetname, self, self)
#self.caller.msg("Imported %s" % cmdsetname)
#self.caller.msg(cmdsethandler.CACHED_CMDSETS)

View file

@ -7,6 +7,7 @@ be of use when designing your own game.
import os
import textwrap
import datetime
from twisted.internet import threads
from django.conf import settings
from src.utils import ansi
@ -335,3 +336,35 @@ def format_table(table, extra_space=1):
ftable.append([str(col[irow]).ljust(max_widths[icol]) + " " * extra_space
for icol, col in enumerate(table)])
return ftable
def run_async(async_func, at_return=None, at_err=None):
"""
This wrapper will use Twisted's asynchronous features to run a slow
function using a separate reactor thread. In effect this means that
the server will not be blocked while the slow process finish.
Use this function with restrain and only for features/commands
that you know has no influence on the cause-and-effect order of your
game (commands given after the async function might be executed before
it has finished).
async_func() - function that should be run asynchroneously
at_return(r) - if given, this function will be called when async_func returns
value r at the end of a successful execution
at_err(e) - if given, this function is called if async_func fails with an exception e.
use e.trap(ExceptionType1, ExceptionType2)
"""
# create deferred object
deferred = threads.deferToThread(async_func)
if at_return:
deferred.addCallback(at_return)
if at_err:
deferred.addErrback(at_err)
# always add a logging errback as a last catch
def default_errback(e):
from src.utils import logger
logger.log_trace(e)
deferred.addErrback(default_errback)