Made TickerHandler more general.
This commit is contained in:
parent
205960948d
commit
afc7fd758f
1 changed files with 31 additions and 31 deletions
|
|
@ -9,36 +9,35 @@ method "at_tick".
|
||||||
from twisted.internet.task import LoopingCall
|
from twisted.internet.task import LoopingCall
|
||||||
from src.server.models import ServerConfig
|
from src.server.models import ServerConfig
|
||||||
from src.utils.logger import log_trace
|
from src.utils.logger import log_trace
|
||||||
from src.utils.utils import to_str
|
|
||||||
from src.utils.dbserialize import dbserialize, dbunserialize, pack_dbobj, unpack_dbobj
|
from src.utils.dbserialize import dbserialize, dbunserialize, pack_dbobj, unpack_dbobj
|
||||||
|
|
||||||
_GA = object.__getattribute__
|
_GA = object.__getattribute__
|
||||||
_SA = object.__setattr__
|
_SA = object.__setattr__
|
||||||
|
|
||||||
|
|
||||||
class _Ticker(object):
|
class Ticker(object):
|
||||||
"""
|
"""
|
||||||
Represents a repeatedly running task that calls
|
Represents a repeatedly running task that calls
|
||||||
hooks repeatedly.
|
hooks repeatedly.
|
||||||
"""
|
"""
|
||||||
def __init__(self, interval, hook_key="at_tick"):
|
def __init__(self, interval):
|
||||||
"""
|
"""
|
||||||
Set up the ticker
|
Set up the ticker
|
||||||
"""
|
"""
|
||||||
def callback(self):
|
def callback(self):
|
||||||
"This should be fed _Task as argument"
|
"This should be fed _Task as argument"
|
||||||
hook_key = self.hook_key
|
for key, (obj, args, kwargs) in self.subscriptions.items():
|
||||||
for key, obj in self.subscriptions.items():
|
hook_key = kwargs.get("hook_key", "at_tick")
|
||||||
try:
|
try:
|
||||||
_GA(obj, hook_key)()
|
_GA(obj, hook_key)(*args, **kwargs)
|
||||||
except Exception:
|
except Exception:
|
||||||
log_trace()
|
log_trace()
|
||||||
|
|
||||||
self.interval = interval
|
self.interval = interval
|
||||||
self.hook_key = hook_key
|
|
||||||
self.subscriptions = {}
|
self.subscriptions = {}
|
||||||
self.task = LoopingCall(callback, self)
|
self.task = LoopingCall(callback, self)
|
||||||
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
"""
|
"""
|
||||||
Start/stop the task depending on how many
|
Start/stop the task depending on how many
|
||||||
|
|
@ -55,11 +54,11 @@ class _Ticker(object):
|
||||||
elif subs:
|
elif subs:
|
||||||
self.task.start(self.interval, now=False)
|
self.task.start(self.interval, now=False)
|
||||||
|
|
||||||
def add(self, store_key, obj):
|
def add(self, store_key, obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Sign up a subscriber to this ticker
|
Sign up a subscriber to this ticker
|
||||||
"""
|
"""
|
||||||
self.subscriptions[store_key] = obj
|
self.subscriptions[store_key] = (obj, args, kwargs)
|
||||||
self.validate()
|
self.validate()
|
||||||
|
|
||||||
def remove(self, store_key):
|
def remove(self, store_key):
|
||||||
|
|
@ -76,22 +75,22 @@ class _Ticker(object):
|
||||||
self.subscriptions = {}
|
self.subscriptions = {}
|
||||||
self.validate()
|
self.validate()
|
||||||
|
|
||||||
class _TickerPool(object):
|
class TickerPool(object):
|
||||||
"""
|
"""
|
||||||
This maintains a pool of Twisted LoopingCall tasks
|
This maintains a pool of Twisted LoopingCall tasks
|
||||||
for calling subscribed objects at given times.
|
for calling subscribed objects at given times.
|
||||||
"""
|
"""
|
||||||
def __init__(self, hook_key="at_tick"):
|
def __init__(self):
|
||||||
"Initialize the pool"
|
"Initialize the pool"
|
||||||
self.tickers = {}
|
self.tickers = {}
|
||||||
|
|
||||||
def add(self, store_key, obj, interval, hook_key="at_tick"):
|
def add(self, store_key, obj, interval, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Add new ticker subscriber
|
Add new ticker subscriber
|
||||||
"""
|
"""
|
||||||
if interval not in self.tickers:
|
if interval not in self.tickers:
|
||||||
self.tickers[interval] = _Ticker(interval, hook_key=hook_key)
|
self.tickers[interval] = Ticker(interval)
|
||||||
self.tickers[interval].add(store_key, obj)
|
self.tickers[interval].add(store_key, obj, *args, **kwargs)
|
||||||
|
|
||||||
def remove(self, store_key, interval):
|
def remove(self, store_key, interval):
|
||||||
"""
|
"""
|
||||||
|
|
@ -119,14 +118,15 @@ class TickerHandler(object):
|
||||||
objects to various tick rates. The pool maintains creation
|
objects to various tick rates. The pool maintains creation
|
||||||
instructions and and re-applies them at a server restart.
|
instructions and and re-applies them at a server restart.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self, save_name="ticker_storage"):
|
||||||
"""
|
"""
|
||||||
Initialize handler
|
Initialize handler
|
||||||
"""
|
"""
|
||||||
self.ticker_storage = {}
|
self.ticker_storage = {}
|
||||||
self.ticker_pool = _TickerPool()
|
self.save_name = save_name
|
||||||
|
self.ticker_pool = TickerPool()
|
||||||
|
|
||||||
def _store_key(self, obj, interval, hook_key):
|
def _store_key(self, obj, interval):
|
||||||
"""
|
"""
|
||||||
Tries to create a store_key for the object.
|
Tries to create a store_key for the object.
|
||||||
Returns a tuple (isdb, store_key) where isdb
|
Returns a tuple (isdb, store_key) where isdb
|
||||||
|
|
@ -155,7 +155,7 @@ class TickerHandler(object):
|
||||||
objkey = id(obj)
|
objkey = id(obj)
|
||||||
isdb = False
|
isdb = False
|
||||||
# return sidb and store_key
|
# return sidb and store_key
|
||||||
return isdb, (objkey, interval, hook_key)
|
return isdb, (objkey, interval)
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -164,42 +164,42 @@ class TickerHandler(object):
|
||||||
"""
|
"""
|
||||||
#print "save:", self.ticker_storage
|
#print "save:", self.ticker_storage
|
||||||
if self.ticker_storage:
|
if self.ticker_storage:
|
||||||
ServerConfig.objects.conf(key="ticker_storage",
|
ServerConfig.objects.conf(key=self.save_name,
|
||||||
value=dbserialize(self.ticker_storage))
|
value=dbserialize(self.ticker_storage))
|
||||||
else:
|
else:
|
||||||
ServerConfig.objects.conf(key="ticker_storage", delete=True)
|
ServerConfig.objects.conf(key=self.save_name, delete=True)
|
||||||
|
|
||||||
def restore(self):
|
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
|
# load stored command instructions and use them to re-initialize handler
|
||||||
ticker_storage = ServerConfig.objects.conf(key="ticker_storage")
|
ticker_storage = ServerConfig.objects.conf(key=self.save_name)
|
||||||
if ticker_storage:
|
if ticker_storage:
|
||||||
self.ticker_storage = dbunserialize(ticker_storage)
|
self.ticker_storage = dbunserialize(ticker_storage)
|
||||||
#print "restore:", self.ticker_storage
|
print "restore:", self.ticker_storage
|
||||||
for (obj, interval, hook_key) in self.ticker_storage.values():
|
for (obj, interval), (args, kwargs) in self.ticker_storage.items():
|
||||||
obj = unpack_dbobj(obj)
|
obj = unpack_dbobj(obj)
|
||||||
_, store_key = self._store_key(obj, interval, hook_key)
|
_, store_key = self._store_key(obj, interval)
|
||||||
self.ticker_pool.add(store_key, obj, interval, hook_key)
|
self.ticker_pool.add(store_key, obj, interval, *args, **kwargs)
|
||||||
|
|
||||||
def add(self, obj, interval, hook_key="at_tick"):
|
def add(self, obj, interval, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Add object to tickerhandler. The object must have an at_tick
|
Add object to tickerhandler. The object must have an at_tick
|
||||||
method. This will be called every interval seconds until the
|
method. This will be called every interval seconds until the
|
||||||
object is unsubscribed from the ticker.
|
object is unsubscribed from the ticker.
|
||||||
"""
|
"""
|
||||||
isdb, store_key = self._store_key(obj, interval, hook_key)
|
isdb, store_key = self._store_key(obj, interval)
|
||||||
if isdb:
|
if isdb:
|
||||||
self.ticker_storage[store_key] = store_key
|
self.ticker_storage[store_key] = (args, kwargs)
|
||||||
self.save()
|
self.save()
|
||||||
self.ticker_pool.add(store_key, obj, interval, hook_key)
|
self.ticker_pool.add(store_key, obj, interval, *args, **kwargs)
|
||||||
|
|
||||||
def remove(self, obj, interval, hook_key="at_tick"):
|
def remove(self, obj, interval):
|
||||||
"""
|
"""
|
||||||
Remove object from ticker with given interval.
|
Remove object from ticker with given interval.
|
||||||
"""
|
"""
|
||||||
isdb, store_key = self._store_key(obj, interval, hook_key)
|
isdb, store_key = self._store_key(obj, interval)
|
||||||
if isdb:
|
if isdb:
|
||||||
self.ticker_storage.pop(store_key, None)
|
self.ticker_storage.pop(store_key, None)
|
||||||
self.save()
|
self.save()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue