Server Stats: use twisted asynchronous adbapi

This commit is contained in:
albertosottile 2018-07-26 11:42:17 +02:00
parent d1e0c974da
commit 6564f22d3a

View File

@ -8,6 +8,7 @@ import sqlite3
import time import time
from string import Template from string import Template
from twisted.enterprise import adbapi
from twisted.internet import task, reactor from twisted.internet import task, reactor
from twisted.internet.protocol import Factory from twisted.internet.protocol import Factory
@ -41,12 +42,11 @@ class SyncFactory(Factory):
self._roomManager = RoomManager() self._roomManager = RoomManager()
else: else:
self._roomManager = PublicRoomManager() self._roomManager = PublicRoomManager()
if statsDbFile is not None: if statsDbFile is not None:
self.statsDbHandle = self._connectToStatsDb(statsDbFile) statsDelay = 5*(int(self.port)%10 + 1)
logDelay = 5*(int(self.port)%10 + 1) StatsRecorder(statsDbFile, self._roomManager, statsDelay)
reactor.callLater(logDelay, self._scheduleClientSnapshot, self.statsDbHandle) else:
else: self.statsDbHandle = None
self.statsDbHandle = None
def buildProtocol(self, addr): def buildProtocol(self, addr):
return SyncServerProtocol(self) return SyncServerProtocol(self)
@ -193,17 +193,33 @@ class SyncFactory(Factory):
else: else:
watcher.setPlaylistIndex(room.getName(), room.getPlaylistIndex()) watcher.setPlaylistIndex(room.getName(), room.getPlaylistIndex())
def _connectToStatsDb(self, dbPath): class StatsRecorder(object):
conn = sqlite3.connect(dbPath) def __init__(self, dbpath, roomManager, delay):
c = conn.cursor() self._roomManagerHandle = roomManager
c.execute('create table if not exists clients_snapshots (snapshot_time integer, version string)') self._dbpool = self._initDatabase(dbpath)
conn.commit() reactor.callLater(delay, self._scheduleClientSnapshot)
return conn
def __del__(self):
def _scheduleClientSnapshot(self, dbHandler): self._dbpool.close()
self._clientSnapshotTimer = task.LoopingCall(self._roomManager.runClientSnapshot, dbHandler)
self._clientSnapshotTimer.start(constants.SERVER_STATS_SNAPSHOT_INTERVAL) def _initDatabase(self, dbPath):
dbpool = adbapi.ConnectionPool("sqlite3", dbPath)
query = 'create table if not exists clients_snapshots (snapshot_time integer, version string)'
dbpool.runQuery(query)
return dbpool
def _scheduleClientSnapshot(self):
self._clientSnapshotTimer = task.LoopingCall(self._runClientSnapshot)
self._clientSnapshotTimer.start(constants.SERVER_STATS_SNAPSHOT_INTERVAL)
def _runClientSnapshot(self):
snapshotTime = int(time.time())
rooms = self._roomManagerHandle.exportRooms()
for room in rooms.values():
for watcher in room.getWatchers():
content = (snapshotTime, watcher.getVersion(), )
self._dbpool.runQuery("INSERT INTO clients_snapshots VALUES (?, ?)", content)
class RoomManager(object): class RoomManager(object):
def __init__(self): def __init__(self):
@ -263,6 +279,9 @@ class RoomManager(object):
while username.lower() in allnames: while username.lower() in allnames:
username += '_' username += '_'
return username return username
def exportRooms(self):
return self._rooms
class PublicRoomManager(RoomManager): class PublicRoomManager(RoomManager):
@ -279,16 +298,6 @@ class PublicRoomManager(RoomManager):
RoomManager.moveWatcher(self, watcher, room) RoomManager.moveWatcher(self, watcher, room)
watcher.setFile(watcher.getFile()) watcher.setFile(watcher.getFile())
def runClientSnapshot(self, dbHandler):
snapshotTime = int(time.time())
c = dbHandler.cursor()
for idx, room in enumerate(self._rooms.values()):
playStatus = room.isPlaying()
for watcher in room.getWatchers():
content = (snapshotTime, watcher.getVersion(), )
c.execute("INSERT INTO clients_snapshots VALUES (?, ?)", content)
dbHandler.commit()
class Room(object): class Room(object):
STATE_PAUSED = 0 STATE_PAUSED = 0