Implemented persistent cache, events and gametime counter.

OBS - there is a new data table (for the persistent cache) so you need to sync or restart with your database.

* Persistent cache (pcache)- this works the same as the volatile cache, except it is regularly saved to disk and recovered upon restart. How often the pcache is backed up is set in preferences. This was heck of a tricky thing to get right due to the intricacies of pickle; for example it turns out there is a bug in cPickle, so only normal pickle works to store the cache objects.
* Persistent events - this makes use of the pcache to re-load the scheduled events every reload. Only events with the property "persistent" will be saved this way (if not set, events will get lost upon reboot, just like now). All the main system events have been implemented as persistent events, including a new event to regularly save the pcache to disk.
* In order to track persistent event timers across reboots, there is also a global "game time" defined now. This is saved in cache and counts seconds only when the server is running. Event timers are adjusted with an offset when restarting (otherwise they will be confused by the real time jumping forward after a downtime). There are also a small set of helpful routines in src/gametime.py to help convert from real time to game time (for easy creation of new events).
* Various info commands have been updated to incoorporate the time stamp and the cache sync information.
* There are a few test commands commented out in commands/general.py that I used for testing; I left them in if you want to test things quickly. It works here, but as always more people testing is needed.
/Griatch
This commit is contained in:
Griatch 2009-11-22 21:18:55 +00:00
parent 5e866c6b73
commit 1ea7e69821
16 changed files with 761 additions and 146 deletions

View file

@ -59,17 +59,6 @@ def cmd_password(command):
source_object.emit_to("Password changed.")
GLOBAL_CMD_TABLE.add_command("@password", cmd_password, help_category="System")
def cmd_pemit(command):
"""
@pemit
Emits something to a player.
(Not yet implemented)
"""
# TODO: Implement cmd_pemit
#GLOBAL_CMD_TABLE.add_command("@pemit", cmd_pemit)
def cmd_emit(command):
"""
@emit
@ -527,7 +516,7 @@ def cmd_fsay(command):
# permission check
if not source_object.controls_other(target):
source_object.emit_to("Cannot pose %s (you don's control it)" % obj.get_name())
source_object.emit_to("Cannot pose %s (you don's control it)" % target.get_name())
return
# Feedback for the object doing the talking.
@ -624,7 +613,7 @@ def cmd_fpose(command):
# permission check
if not source_object.controls_other(target):
source_object.emit_to("Cannot pose %s (you don's control it)" % obj.get_name())
source_object.emit_to("Cannot pose %s (you don's control it)" % target.get_name())
return
if "nospace" in command.command_switches:
@ -776,6 +765,8 @@ def cmd_help(command):
source_object.emit_to(string)
GLOBAL_CMD_TABLE.add_command("help", cmd_help)
## def cmd_testevent(command):
## from src import events
## from src import scheduler
@ -793,3 +784,33 @@ GLOBAL_CMD_TABLE.add_command("help", cmd_help)
## scheduler.del_event(pid)
## source_object.emit_to("event with pid %s removed (if it existed)." % pid)
## GLOBAL_CMD_TABLE.add_command("testevent", cmd_testevent)
## def cmd_testcache(command):
## from src.cache import cache
## from src import scheduler
## from src import events
## from src import gametime
## source_object = command.source_object
## switches = command.command_switches
## s1 = "Temp_cache_val_OK"
## s2 = "Perm_cache_val_OK"
## s3 = "Perm_cache_val2_OK"
## if switches and "get" in switches:
## cache.load_pcache()
## cache_vol = source_object.cache.testcache
## source_object.emit_to("< volatile cache: %s" % cache_vol)
## cache_perm = source_object.pcache.testcache_perm
## source_object.emit_to("< cache_perm1: %s" % cache_perm)
## cache_perm2 = cache.get_pcache("permtest2")
## source_object.emit_to("< cache_perm2: %s" % cache_perm2)
## else:
## source_object.cache.testcache = s1
## source_object.pcache.testcache_perm = s2
## cache.set_pcache("permtest2", s3)
## source_object.emit_to("> volatile cache: %s" % s1)
## source_object.emit_to("> cache_perm1: %s" % s2)
## source_object.emit_to("> cache_perm2: %s" % s3)
## cache.save_pcache()
## source_object.emit_to("Caches saved.")
## source_object.emit_to("Time: %i" % gametime.time())
## GLOBAL_CMD_TABLE.add_command("testcache", cmd_testcache)

View file

@ -14,6 +14,8 @@ from src import scheduler
from src import defines_global
from src import flags
from src.cmdtable import GLOBAL_CMD_TABLE
from src.cache import cache
from src import gametime
def cmd_version(command):
"""
@ -40,8 +42,14 @@ def cmd_time(command):
Server local time.
"""
command.source_object.emit_to('Current server time : %s' %
(time.strftime('%a %b %d %H:%M:%S %Y (%Z)', time.localtime(),)))
gtime = gametime.time()
synctime = gametime.time_last_sync()
ltime = time.strftime('%a %b %d %H:%M:%S %Y (%Z)', time.localtime())
string = " Current game time: %i s." % gtime
string += "\n Time since cache was last saved: %i s." % synctime
string += "\n Current server time: %s" % ltime
command.source_object.emit_to(string)
GLOBAL_CMD_TABLE.add_command("@time", cmd_time, priv_tuple=("genperms.game_info",),
help_category="Admin")
@ -175,3 +183,22 @@ def cmd_stats(command):
stats_dict["players"],
stats_dict["garbage"]))
GLOBAL_CMD_TABLE.add_command("@stats", cmd_stats, priv_tuple=("genperms.game_info",), help_category="Admin"),
def cmd_showcache(command):
"""
@showcache - show stats about the cache system
Usage:
@showcache
Study the current contents and size of the cache.
"""
source_object = command.source_object
str_cache, str_pcache = cache.show()
string = ""
if str_cache:
string += "\nVolatile cache:\n " + str_cache
if str_pcache:
string += "\nPersistent cache:\n " + str_pcache
source_object.emit_to(string)
GLOBAL_CMD_TABLE.add_command("@showcache", cmd_showcache, priv_tuple=("genperms.game_info",), help_category="Admin"),