Modified contrib/evlang to optionally make use of ProcPool multiprocessing.

This commit is contained in:
Griatch 2012-09-03 19:21:04 +02:00
parent ffcf4b3c2f
commit 5c6ee44039
3 changed files with 25 additions and 13 deletions

View file

@ -4,7 +4,7 @@ Dice - rolls dice for roleplaying, in-game gambling or GM:ing
Evennia contribution - Griatch 2012 Evennia contribution - Griatch 2012
This module implements a full-fledge dice-roller and a 'dice' command to This module implements a full-fledged dice-roller and a 'dice' command to
go with it. It uses standard RPG 'd'-syntax (e.g. 2d6 to roll two go with it. It uses standard RPG 'd'-syntax (e.g. 2d6 to roll two
six-sided die) and also supports modifiers such as 3d6 + 5. six-sided die) and also supports modifiers such as 3d6 + 5.
@ -21,7 +21,7 @@ Installation:
To use in your code, just import the roll_dice function from this module. To use in your code, just import the roll_dice function from this module.
To use the dice/roll command, just import this module in your custom To use the dice/roll command, just import this module in your custom
cmdset module and add the following line to the end of OOCCmdSet's cmdset module and add the following line to the end of DefaultCmdSet's
at_cmdset_creation(): at_cmdset_creation():
self.add(dice.CmdDice()) self.add(dice.CmdDice())
@ -93,7 +93,7 @@ RE_COND = re.compile(r"(<|>|<=|>=|!=|==)")
class CmdDice(default_cmds.MuxCommand): class CmdDice(default_cmds.MuxCommand):
""" """
roll a dice roll dice
Usage: Usage:
dice[/switch] <nr>d<sides> [modifier] [success condition] dice[/switch] <nr>d<sides> [modifier] [success condition]

View file

@ -84,7 +84,8 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspa
from django.core.management import setup_environ from django.core.management import setup_environ
from game import settings from game import settings
setup_environ(settings) setup_environ(settings)
from ev import logger from src.utils.utils import run_async
_LOGGER = None
#------------------------------------------------------------ #------------------------------------------------------------
# Evennia-specific blocks # Evennia-specific blocks
@ -308,9 +309,12 @@ class Evlang(object):
""" """
def alarm(codestring): def alarm(codestring):
"store the code of too-long-running scripts" "store the code of too-long-running scripts"
global _LOGGER
if not _LOGGER:
from src.utils import logger as _LOGGER
self.timedout_codestrings.append(codestring) self.timedout_codestrings.append(codestring)
err = "Evlang code '%s' exceeded allowed execution time (>%ss)." % (codestring, timeout) err = "Evlang code '%s' exceeded allowed execution time (>%ss)." % (codestring, timeout)
logger.log_errmsg("EVLANG time exceeded: caller: %s, scripter: %s, code: %s" % (caller, scripter, codestring)) _LOGGER.log_errmsg("EVLANG time exceeded: caller: %s, scripter: %s, code: %s" % (caller, scripter, codestring))
if not self.msg(err, scripter, caller): if not self.msg(err, scripter, caller):
raise EvlangError(err) raise EvlangError(err)
def errback(f): def errback(f):
@ -702,10 +706,10 @@ class LimitedExecVisitor(object):
def visitPower(self, node, *args): def visitPower(self, node, *args):
"Make sure power-of operations don't get too big" "Make sure power-of operations don't get too big"
if node.left.value > 1000000 or node.right.value > 10000: if node.left.value > 1000000 or node.right.value > 10:
lineno = get_node_lineno(node) lineno = get_node_lineno(node)
self.errors.append(LimitedExecAttrError( \ self.errors.append(LimitedExecAttrError( \
"power law index too big - restricted", lineno)) "power law solution too big - restricted", lineno))
def ok(self, node, *args): def ok(self, node, *args):
"Default callback for 'harmless' AST nodes." "Default callback for 'harmless' AST nodes."
@ -802,7 +806,7 @@ def validate_code(codestring):
raise LimitedExecCodeException(codestring, checker.errors) raise LimitedExecCodeException(codestring, checker.errors)
return True return True
def limited_exec(code, context = {}, timeout_secs = 2): def limited_exec(code, context = {}, timeout_secs = 2, retobj=None):
""" """
Validate source code and make sure it contains no unauthorized Validate source code and make sure it contains no unauthorized
expression/statements as configured via 'UNALLOWED_AST_NODES' and expression/statements as configured via 'UNALLOWED_AST_NODES' and
@ -824,9 +828,16 @@ def limited_exec(code, context = {}, timeout_secs = 2):
if code did not execute within the given timelimit = if code did not execute within the given timelimit =
LimitedExecTimeoutException LimitedExecTimeoutException
""" """
# run code only after validation has completed if retobj:
if validate_context(context) and validate_code(code): callback = lambda r: retobj.msg(r)
exec code in context errback = lambda e: retobj.msg(e)
# run code only after validation has completed
if validate_context(context) and validate_code(code):
run_async(code, *context, at_return=callback, at_err=errback)
else:
# run code only after validation has completed
if validate_context(context) and validate_code(code):
run_async(code, *context)

View file

@ -222,9 +222,10 @@ BASE_OBJECT_TYPECLASS = "src.objects.objects.Object"
BASE_CHARACTER_TYPECLASS = "src.objects.objects.Character" BASE_CHARACTER_TYPECLASS = "src.objects.objects.Character"
# Typeclass for rooms (fallback) # Typeclass for rooms (fallback)
BASE_ROOM_TYPECLASS = "src.objects.objects.Room" BASE_ROOM_TYPECLASS = "src.objects.objects.Room"
# Typeclass for Exit objects (fallback) # Typeclass for Exit objects (fallback).
BASE_EXIT_TYPECLASS = "src.objects.objects.Exit" BASE_EXIT_TYPECLASS = "src.objects.objects.Exit"
# Typeclass for Scripts (fallback) # Typeclass for Scripts (fallback). You usually don't need to change this
# but create custom variations of scripts on a per-case basis instead.
BASE_SCRIPT_TYPECLASS = "src.scripts.scripts.DoNothing" BASE_SCRIPT_TYPECLASS = "src.scripts.scripts.DoNothing"
# The home location for new characters. This must be a unique # The home location for new characters. This must be a unique
# dbref (default is Limbo #2). If you want more advanced control over # dbref (default is Limbo #2). If you want more advanced control over