From 914c32ece80e41ff969ddb8ef8939fcdc26b471e Mon Sep 17 00:00:00 2001 From: m!nus Date: Tue, 16 Sep 2014 19:46:14 +0200 Subject: [PATCH] added statscollector statscollector continuously monitors all servers and writes their current state to redis --- statscollector.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 statscollector.py diff --git a/statscollector.py b/statscollector.py new file mode 100644 index 0000000..87b8f7b --- /dev/null +++ b/statscollector.py @@ -0,0 +1,65 @@ +import redis +from teeworlds import query_masters_serverlist, create_masters, EventSocket, MasterServer, Player +from teeworlds.base import Address +from teeworlds.server import Server +import json +from teeworlds.teeworlds import query_masters_serverlist +from json import JSONEncoder + +MASTER_REFRESH_INTERVAL = 60 +SERVER_REFRESH_INTERVAL = 120 +SERVER_TIMEOUT = 300 +PLAYER_TIMEOUT = SERVER_TIMEOUT + +# Featues +# - server list → redis set +# - server details → redis key (server:ip:port) +# - online players → server mapping → redis hash + + +class TeeworldsJSONEncoder(JSONEncoder): + def default(self, o): + if isinstance(o, Address): + return str(o) + elif isinstance(o, Server): + return str(o.address) + elif isinstance(o, Player): + return o.name + else: + return JSONEncoder.default(self, o) + +rconn = redis.StrictRedis() + +class RefreshingServer(Server): + def on_info_received(self): + server_info = json.dumps({k: v for k, v in filter(lambda it: not it[0].startswith("_"), self.__dict__.items())}, cls=TeeworldsJSONEncoder) + detail_key_name = "server:{}".format(str(self.address)) + rconn.set(detail_key_name, server_info, ex=SERVER_TIMEOUT) + for player in self.playerlist: + player_key_name = "player:{}:{}".format(player.name, str(self.address)) + player_info = json.dumps({k: v for k, v in filter(lambda it: not it[0].startswith("_"), player.__dict__.items())}, cls=TeeworldsJSONEncoder) + rconn.set(player_key_name, player_info, ex=PLAYER_TIMEOUT) + self._socket.call_later(SERVER_REFRESH_INTERVAL, self.request_info) + #self._socket.call_later(SERVER_TIMEOUT, self.on_timeout) + + # def on_timeout(self): + # # TODO: clean requests from EventSocket + # pass + +class RefreshingMaster(MasterServer): + server_factory = RefreshingServer + + def on_list_request(self, request): + self._socket.call_later(MASTER_REFRESH_INTERVAL, self.request_list) + + def on_server_add(self, server): + server.request_info() + + +e = EventSocket(max_packet_rate=50) +m = create_masters(e, master_factory=RefreshingMaster) +query_masters_serverlist([m[0]]) +#for m in t.masterlist: +# m.on_server_add = lambda s: s.request_info() +#t.query_masters() +e.run() \ No newline at end of file -- GitLab