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 django.db import IntegrityError
from src.comms.models import Msg from src.comms.models import Msg
from src.permissions import permissions from src.permissions import permissions
from src.utils import create from src.utils import create, debug, utils
from src.utils import debug
from game.gamesrc.commands.default.muxcommand import MuxCommand from game.gamesrc.commands.default.muxcommand import MuxCommand
from src.commands import cmdsethandler from src.commands import cmdsethandler
@ -29,17 +28,38 @@ class CmdTest(MuxCommand):
key = "@test" key = "@test"
aliases = ["@te", "@test all"] aliases = ["@te", "@test all"]
permissions = "cmd:Immortals Wizards" #permissions = "cmd:Immortals" #Wizards
# the muxcommand class itself handles the display # the muxcommand class itself handles the display
# so we just defer to it by not adding any function. # so we just defer to it by not adding any function.
def func(self): def func(self):
cmdsetname = "game.gamesrc.commands.default.cmdset_default.DefaultCmdSet"
self.caller.msg(cmdsethandler.CACHED_CMDSETS) def test():
cmdsethandler.import_cmdset(cmdsetname, self, self) li = []
self.caller.msg("Imported %s" % cmdsetname) for l in range(10000):
self.caller.msg(cmdsethandler.CACHED_CMDSETS) 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 os
import textwrap import textwrap
import datetime import datetime
from twisted.internet import threads
from django.conf import settings from django.conf import settings
from src.utils import ansi 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 ftable.append([str(col[irow]).ljust(max_widths[icol]) + " " * extra_space
for icol, col in enumerate(table)]) for icol, col in enumerate(table)])
return ftable 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)