mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Twisted min version upped to 15.2.1 due to a change in the LoopingCall infrastructure that Evennia relies on. This resolves #744 by updating the Evennia implementation accordingly.
This commit is contained in:
parent
ff4013a58a
commit
97e04ee710
6 changed files with 61 additions and 83 deletions
|
|
@ -8,7 +8,6 @@ ability to run timers.
|
|||
from twisted.internet.defer import Deferred, maybeDeferred
|
||||
from twisted.internet.task import LoopingCall
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.conf import settings
|
||||
from evennia.typeclasses.models import TypeclassBase
|
||||
from evennia.scripts.models import ScriptDB
|
||||
from evennia.scripts.manager import ScriptManager
|
||||
|
|
@ -40,7 +39,7 @@ class ExtendedLoopingCall(LoopingCall):
|
|||
interval (int): Repeat interval in seconds.
|
||||
now (bool, optional): Whether to start immediately or after
|
||||
`start_delay` seconds.
|
||||
start_delay (bool: The number of seconds before starting.
|
||||
start_delay (int): The number of seconds before starting.
|
||||
If None, wait interval seconds. Only valid if `now` is `False`.
|
||||
It is used as a way to start with a variable start time
|
||||
after a pause.
|
||||
|
|
@ -64,44 +63,40 @@ class ExtendedLoopingCall(LoopingCall):
|
|||
"ExtendedLoopingCall.")
|
||||
if interval < 0:
|
||||
raise ValueError, "interval must be >= 0"
|
||||
|
||||
self.running = True
|
||||
d = self.deferred = Deferred()
|
||||
self.starttime = self.clock.seconds()
|
||||
self._expectNextCallAt = self.starttime
|
||||
self.interval = interval
|
||||
self._runAtStart = now
|
||||
self.callcount = max(0, count_start)
|
||||
self.start_delay = start_delay if start_delay is None else max(0, start_delay)
|
||||
|
||||
if now:
|
||||
# run immediately
|
||||
self()
|
||||
elif start_delay is not None and start_delay >= 0:
|
||||
# start after some time: for this to work we need to
|
||||
# trick _scheduleFrom by temporarily setting a different
|
||||
# self.interval for it to check.
|
||||
real_interval, self.interval = self.interval, start_delay
|
||||
self._scheduleFrom(self.starttime)
|
||||
# re-set the actual interval (this will be picked up
|
||||
# next time it runs
|
||||
self.interval = real_interval
|
||||
else:
|
||||
if start_delay is not None and start_delay >= 0:
|
||||
# we set `start_delay` after the `_reschedule` call to make
|
||||
# next_call_time() find it until next reschedule.
|
||||
self.interval = start_delay
|
||||
self._reschedule()
|
||||
self.interval = interval
|
||||
self.start_delay = start_delay
|
||||
else:
|
||||
self._reschedule()
|
||||
self._scheduleFrom(self.starttime)
|
||||
return d
|
||||
|
||||
def __call__(self):
|
||||
"""
|
||||
Tick one step
|
||||
Tick one step. We update callcount (tracks number of calls) as
|
||||
well as null start_delay (needed in order to correctly
|
||||
estimate next_call_time at all times).
|
||||
|
||||
"""
|
||||
self.callcount += 1
|
||||
super(ExtendedLoopingCall, self).__call__()
|
||||
|
||||
def _reschedule(self):
|
||||
"""
|
||||
Handle call rescheduling including nulling `start_delay` and
|
||||
stopping if number of repeats is reached.
|
||||
|
||||
"""
|
||||
self.start_delay = None
|
||||
super(ExtendedLoopingCall, self)._reschedule()
|
||||
super(ExtendedLoopingCall, self).__call__()
|
||||
|
||||
def force_repeat(self):
|
||||
"""
|
||||
|
|
@ -116,22 +111,24 @@ class ExtendedLoopingCall(LoopingCall):
|
|||
"that was not running.")
|
||||
if self.call is not None:
|
||||
self.call.cancel()
|
||||
self._expectNextCallAt = self.clock.seconds()
|
||||
self.call.callback()
|
||||
self()
|
||||
|
||||
def next_call_time(self):
|
||||
"""
|
||||
Get the next call time.
|
||||
Get the next call time. This also takes the eventual effect
|
||||
of start_delay into account.
|
||||
|
||||
Returns:
|
||||
next (int): The time in seconds until the next call. This
|
||||
next (int or None): The time in seconds until the next call. This
|
||||
takes `start_delay` into account. Returns `None` if
|
||||
the task is not running.
|
||||
|
||||
"""
|
||||
if self.running:
|
||||
currentTime = self.clock.seconds()
|
||||
return self._expectNextCallAt - currentTime
|
||||
total_runtime = self.clock.seconds() - self.starttime
|
||||
interval = self.start_delay or self.interval
|
||||
return interval - (total_runtime % self.interval)
|
||||
return None
|
||||
|
||||
class ScriptBase(ScriptDB):
|
||||
|
|
|
|||
|
|
@ -264,7 +264,10 @@ class TickerHandler(object):
|
|||
|
||||
def restore(self):
|
||||
"""
|
||||
Restore ticker_storage from database and re-initialize the handler from storage. This is triggered by the server at restart.
|
||||
Restore ticker_storage from database and re-initialize the
|
||||
handler from storage. This is triggered by the server at
|
||||
restart.
|
||||
|
||||
"""
|
||||
# load stored command instructions and use them to re-initialize handler
|
||||
ticker_storage = ServerConfig.objects.conf(key=self.save_name)
|
||||
|
|
@ -353,7 +356,9 @@ class TickerHandler(object):
|
|||
"""
|
||||
self.ticker_pool.stop(interval)
|
||||
if interval:
|
||||
self.ticker_storage = dict((store_key, store_key) for store_key in self.ticker_storage if store_key[1] != interval)
|
||||
self.ticker_storage = dict((store_key, store_key)
|
||||
for store_key in self.ticker_storage
|
||||
if store_key[1] != interval)
|
||||
else:
|
||||
self.ticker_storage = {}
|
||||
self.save()
|
||||
|
|
|
|||
|
|
@ -54,8 +54,9 @@ PORTAL_RESTART = None
|
|||
SERVER_PY_FILE = None
|
||||
PORTAL_PY_FILE = None
|
||||
|
||||
|
||||
PYTHON_MIN = '2.7'
|
||||
TWISTED_MIN = '12.0'
|
||||
TWISTED_MIN = '15.2.1'
|
||||
DJANGO_MIN = '1.8'
|
||||
DJANGO_REC = '1.8'
|
||||
|
||||
|
|
@ -265,10 +266,10 @@ ERROR_PYTHON_VERSION = \
|
|||
{python_min} or higher (but not 3.x).
|
||||
"""
|
||||
|
||||
WARNING_TWISTED_VERSION = \
|
||||
ERROR_TWISTED_VERSION = \
|
||||
"""
|
||||
WARNING: Twisted {tversion} found. Evennia recommends
|
||||
v{twisted_min} or higher."
|
||||
ERROR: Twisted {tversion} found. Evennia requires
|
||||
version {twisted_min} or higher.
|
||||
"""
|
||||
|
||||
ERROR_NOTWISTED = \
|
||||
|
|
@ -334,6 +335,9 @@ def check_main_evennia_dependencies():
|
|||
"""
|
||||
Checks and imports the Evennia dependencies. This must be done
|
||||
already before the paths are set up.
|
||||
|
||||
Returns:
|
||||
not_error (bool): True if no dependency error was found.
|
||||
"""
|
||||
error = False
|
||||
|
||||
|
|
@ -347,7 +351,8 @@ def check_main_evennia_dependencies():
|
|||
import twisted
|
||||
tversion = twisted.version.short()
|
||||
if tversion < TWISTED_MIN:
|
||||
print WARNING_TWISTED_VERSION.format(tversion=tversion, twisted_min=TWISTED_MIN)
|
||||
print ERROR_TWISTED_VERSION.format(tversion=tversion, twisted_min=TWISTED_MIN)
|
||||
error = True
|
||||
except ImportError:
|
||||
print ERROR_NOTWISTED
|
||||
error = True
|
||||
|
|
@ -368,6 +373,8 @@ def check_main_evennia_dependencies():
|
|||
error = True
|
||||
if error:
|
||||
sys.exit()
|
||||
# return True/False if error was reported or not
|
||||
return not error
|
||||
|
||||
|
||||
def set_gamedir(path):
|
||||
|
|
|
|||
|
|
@ -672,68 +672,37 @@ def run_async(to_execute, *args, **kwargs):
|
|||
|
||||
def check_evennia_dependencies():
|
||||
"""
|
||||
Checks the versions of Evennia's dependencies.
|
||||
Checks the versions of Evennia's dependencies including making
|
||||
some checks for runtime libraries
|
||||
|
||||
Returns False if a show-stopping version mismatch is found.
|
||||
"""
|
||||
# defining the requirements
|
||||
python_min = '2.7'
|
||||
twisted_min = '12.0'
|
||||
django_min = '1.8'
|
||||
django_rec = '1.8'
|
||||
|
||||
# check main dependencies
|
||||
from evennia.server.evennia_launcher import check_main_evennia_dependencies
|
||||
not_error = check_main_evennia_dependencies()
|
||||
|
||||
errstring = ""
|
||||
no_error = True
|
||||
|
||||
# Python
|
||||
pversion = ".".join(str(num) for num in sys.version_info if type(num) == int)
|
||||
if pversion < python_min:
|
||||
errstring += "\n ERROR: Python %s used. Evennia requires version %s or higher (but not 3.x)." % (pversion, python_min)
|
||||
no_error = False
|
||||
# Twisted
|
||||
try:
|
||||
import twisted
|
||||
tversion = twisted.version.short()
|
||||
if tversion < twisted_min:
|
||||
errstring += "\n WARNING: Twisted %s found. Evennia recommends v%s or higher." % (twisted.version.short(), twisted_min)
|
||||
except ImportError:
|
||||
errstring += "\n ERROR: Twisted does not seem to be installed."
|
||||
no_error = False
|
||||
# Django
|
||||
try:
|
||||
import django
|
||||
dversion = ".".join(str(num) for num in django.VERSION if type(num) == int)
|
||||
dversion_main = ".".join(dversion.split(".")[:2]) # only the main version (1.5, not 1.5.4.0)
|
||||
if dversion < django_min:
|
||||
errstring += "\n ERROR: Django %s found. Evennia requires version %s or higher." % (dversion, django_min)
|
||||
no_error = False
|
||||
elif django_min <= dversion < django_rec:
|
||||
errstring += "\n NOTE: Django %s found. This will work, but v%s is recommended for production." % (dversion, django_rec)
|
||||
elif django_rec < dversion_main:
|
||||
errstring += "\n NOTE: Django %s found. This is newer than Evennia's recommended version (v%s). It will"
|
||||
errstring += "\n probably work, but may be new enough not to be fully tested yet. Report any issues." % (dversion, django_rec)
|
||||
except ImportError:
|
||||
errstring += "\n ERROR: Django does not seem to be installed."
|
||||
no_error = False
|
||||
# South
|
||||
# South is no longer used ...
|
||||
if 'south' in settings.INSTALLED_APPS:
|
||||
errstring += "\n ERROR: 'south' found in settings.INSTALLED_APPS. South is no longer used. If this was added manually, remove it."
|
||||
no_error = False
|
||||
errstring += "\n ERROR: 'south' found in settings.INSTALLED_APPS. " \
|
||||
"\n South is no longer used. If this was added manually, remove it."
|
||||
not_error = False
|
||||
# IRC support
|
||||
if settings.IRC_ENABLED:
|
||||
try:
|
||||
import twisted.words
|
||||
twisted.words # set to avoid debug info about not-used import
|
||||
except ImportError:
|
||||
errstring += "\n ERROR: IRC is enabled, but twisted.words is not installed. Please install it."
|
||||
errstring += "\n Linux Debian/Ubuntu users should install package 'python-twisted-words', others"
|
||||
errstring += "\n can get it from http://twistedmatrix.com/trac/wiki/TwistedWords."
|
||||
no_error = False
|
||||
errstring += "\n ERROR: IRC is enabled, but twisted.words is not installed. Please install it." \
|
||||
"\n Linux Debian/Ubuntu users should install package 'python-twisted-words', others" \
|
||||
"\n can get it from http://twistedmatrix.com/trac/wiki/TwistedWords."
|
||||
not_error = False
|
||||
errstring = errstring.strip()
|
||||
if errstring:
|
||||
mlen = max(len(line) for line in errstring.split("\n"))
|
||||
print "%s\n%s\n%s" % ("-"*mlen, errstring, '-'*mlen)
|
||||
return no_error
|
||||
return not_error
|
||||
|
||||
|
||||
def has_parent(basepath, obj):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Evennia dependencies, for Linux/Mac platforms
|
||||
|
||||
django >= 1.8, < 1.9
|
||||
twisted >= 12.0
|
||||
twisted >= 15.2.1
|
||||
mock >= 1.0.1
|
||||
pillow
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
pypiwin32
|
||||
# general
|
||||
django >= 1.8, < 1.9
|
||||
twisted >= 12.0
|
||||
twisted >= 15.2.1
|
||||
mock >= 1.0.1
|
||||
pillow
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue