Server locks rooms when sending states now to prevent exceptions
This commit is contained in:
parent
2941cd1849
commit
da94607885
@ -7,6 +7,7 @@ import syncplay
|
|||||||
from syncplay.protocols import SyncServerProtocol
|
from syncplay.protocols import SyncServerProtocol
|
||||||
import time
|
import time
|
||||||
from syncplay import constants
|
from syncplay import constants
|
||||||
|
import threading
|
||||||
|
|
||||||
class SyncFactory(Factory):
|
class SyncFactory(Factory):
|
||||||
def __init__(self, password = ''):
|
def __init__(self, password = ''):
|
||||||
@ -16,19 +17,21 @@ class SyncFactory(Factory):
|
|||||||
self.password = password
|
self.password = password
|
||||||
self._rooms = {}
|
self._rooms = {}
|
||||||
self._roomStates = {}
|
self._roomStates = {}
|
||||||
|
self._roomUpdate = threading.RLock()
|
||||||
|
|
||||||
def buildProtocol(self, addr):
|
def buildProtocol(self, addr):
|
||||||
return SyncServerProtocol(self)
|
return SyncServerProtocol(self)
|
||||||
|
|
||||||
def _createRoomIfDoesntExist(self, roomName):
|
def _createRoomIfDoesntExist(self, roomName):
|
||||||
if (not self._rooms.has_key(roomName)):
|
if (not self._rooms.has_key(roomName)):
|
||||||
self._rooms[roomName] = {}
|
with self._roomUpdate:
|
||||||
self._roomStates[roomName] = {
|
self._rooms[roomName] = {}
|
||||||
"position": 0.0,
|
self._roomStates[roomName] = {
|
||||||
"paused": True,
|
"position": 0.0,
|
||||||
"setBy": None,
|
"paused": True,
|
||||||
"lastUpdate": time.time()
|
"setBy": None,
|
||||||
}
|
"lastUpdate": time.time()
|
||||||
|
}
|
||||||
|
|
||||||
def addWatcher(self, watcherProtocol, username, roomName, roomPassword):
|
def addWatcher(self, watcherProtocol, username, roomName, roomPassword):
|
||||||
allnames = []
|
allnames = []
|
||||||
@ -39,7 +42,8 @@ class SyncFactory(Factory):
|
|||||||
username += '_'
|
username += '_'
|
||||||
self._createRoomIfDoesntExist(roomName)
|
self._createRoomIfDoesntExist(roomName)
|
||||||
watcher = Watcher(self, watcherProtocol, username, roomName)
|
watcher = Watcher(self, watcherProtocol, username, roomName)
|
||||||
self._rooms[roomName][watcherProtocol] = watcher
|
with self._roomUpdate:
|
||||||
|
self._rooms[roomName][watcherProtocol] = watcher
|
||||||
print "{0}({2}) connected to room '{1}'".format(username, roomName, watcherProtocol.transport.getPeer().host)
|
print "{0}({2}) connected to room '{1}'".format(username, roomName, watcherProtocol.transport.getPeer().host)
|
||||||
reactor.callLater(0.1, watcher.scheduleSendState)
|
reactor.callLater(0.1, watcher.scheduleSendState)
|
||||||
l = lambda w: w.sendUserSetting(username, roomName, None, {"joined": True})
|
l = lambda w: w.sendUserSetting(username, roomName, None, {"joined": True})
|
||||||
@ -50,7 +54,7 @@ class SyncFactory(Factory):
|
|||||||
if(room.has_key(watcherProtocol)):
|
if(room.has_key(watcherProtocol)):
|
||||||
return room[watcherProtocol]
|
return room[watcherProtocol]
|
||||||
|
|
||||||
def getAllWatchers(self, watcherProtocol):
|
def getAllWatchers(self, watcherProtocol): #TODO: Optimize me
|
||||||
watchers = {}
|
watchers = {}
|
||||||
for room in self._rooms.itervalues():
|
for room in self._rooms.itervalues():
|
||||||
for watcher in room.itervalues():
|
for watcher in room.itervalues():
|
||||||
@ -59,14 +63,16 @@ class SyncFactory(Factory):
|
|||||||
|
|
||||||
def _removeWatcherFromTheRoom(self, watcherProtocol):
|
def _removeWatcherFromTheRoom(self, watcherProtocol):
|
||||||
for room in self._rooms.itervalues():
|
for room in self._rooms.itervalues():
|
||||||
watcher = room.pop(watcherProtocol, None)
|
with self._roomUpdate:
|
||||||
|
watcher = room.pop(watcherProtocol, None)
|
||||||
if(watcher):
|
if(watcher):
|
||||||
return watcher
|
return watcher
|
||||||
|
|
||||||
def _deleteRoomIfEmpty(self, room):
|
def _deleteRoomIfEmpty(self, room):
|
||||||
if (self._rooms[room] == {}):
|
if (self._rooms[room] == {}):
|
||||||
self._rooms.pop(room)
|
with self._roomUpdate:
|
||||||
self._roomStates.pop(room)
|
self._rooms.pop(room)
|
||||||
|
self._roomStates.pop(room)
|
||||||
|
|
||||||
def getRoomPausedAndPosition(self, room):
|
def getRoomPausedAndPosition(self, room):
|
||||||
position = self._roomStates[room]["position"]
|
position = self._roomStates[room]["position"]
|
||||||
@ -160,7 +166,8 @@ class SyncFactory(Factory):
|
|||||||
watcher.resetStateTimer()
|
watcher.resetStateTimer()
|
||||||
oldRoom = watcher.room
|
oldRoom = watcher.room
|
||||||
self._createRoomIfDoesntExist(room)
|
self._createRoomIfDoesntExist(room)
|
||||||
self._rooms[room][watcherProtocol] = watcher
|
with self._roomUpdate:
|
||||||
|
self._rooms[room][watcherProtocol] = watcher
|
||||||
self._roomStates[room]["position"] = watcher.position
|
self._roomStates[room]["position"] = watcher.position
|
||||||
self._roomStates[room]["setBy"] = watcher.name
|
self._roomStates[room]["setBy"] = watcher.name
|
||||||
self._roomStates[room]["lastUpdate"] = time.time()
|
self._roomStates[room]["lastUpdate"] = time.time()
|
||||||
@ -178,13 +185,15 @@ class SyncFactory(Factory):
|
|||||||
def broadcastRoom(self, sender, what):
|
def broadcastRoom(self, sender, what):
|
||||||
room = self._rooms[self.watcherGetRoom(sender)]
|
room = self._rooms[self.watcherGetRoom(sender)]
|
||||||
if(room):
|
if(room):
|
||||||
for receiver in room:
|
with self._roomUpdate:
|
||||||
what(receiver)
|
for receiver in room:
|
||||||
|
what(receiver)
|
||||||
|
|
||||||
def broadcast(self, sender, what):
|
def broadcast(self, sender, what):
|
||||||
for room in self._rooms.itervalues():
|
with self._roomUpdate:
|
||||||
for receiver in room:
|
for room in self._rooms.itervalues():
|
||||||
what(receiver)
|
for receiver in room:
|
||||||
|
what(receiver)
|
||||||
|
|
||||||
class SyncIsolatedFactory(SyncFactory):
|
class SyncIsolatedFactory(SyncFactory):
|
||||||
def broadcast(self, sender, what):
|
def broadcast(self, sender, what):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user