Compare commits

...

2 commits

Author SHA1 Message Date
Ruben van de Ven
eea090d265 Merge branch 'master' of git.rubenvandeven.com:r/guest_worker 2020-01-22 18:15:56 +01:00
Ruben van de Ven
802b93fa95 Hopefully better handling of abandons 2020-01-22 18:15:47 +01:00
4 changed files with 58 additions and 23 deletions

View file

@ -295,6 +295,17 @@ class CentralManagement():
self.currentHit.open_page_at = datetime.datetime.utcnow() self.currentHit.open_page_at = datetime.datetime.utcnow()
self.store.saveHIT(self.currentHit) self.store.saveHIT(self.currentHit)
self.setLight(True) self.setLight(True)
elif signal.name == 'server.close':
if not signal.params['abandoned']:
continue
a = self.currentHit.getLastAssignment()
if a.assignment_id != signal.params['assignment_id']:
self.logger.info(f"Close of older assignment_id: {signal}")
continue
self.logger.critical(f"Websocket closed of active assignment_id: {signal}")
a.abandoned_at = datetime.datetime.utcnow()
self.store.saveAssignment(a)
self.plotter.park()
elif signal.name == 'assignment.submit': elif signal.name == 'assignment.submit':
a = self.currentHit.getLastAssignment() a = self.currentHit.getLastAssignment()
if a.assignment_id != signal.params['assignment_id']: if a.assignment_id != signal.params['assignment_id']:

View file

@ -56,6 +56,8 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
self.plotterQ = plotterQ self.plotterQ = plotterQ
self.eventQ = eventQ self.eventQ = eventQ
self.store = store self.store = store
self.assignment_id = None
self.abandoned = False
def check_origin(self, origin): def check_origin(self, origin):
parsed_origin = urlparse(origin) parsed_origin = urlparse(origin)
@ -79,7 +81,8 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
if self.assignment.assignment_id != self.assignment_id: if self.assignment.assignment_id != self.assignment_id:
raise Exception(f"Opening websocket for invalid assignment {self.assignment_id}") raise Exception(f"Opening websocket for invalid assignment {self.assignment_id}")
self.timeout = datetime.datetime.now() + datetime.timedelta(seconds=self.store.getHitTimeout()) self.timeout = self.assignment.created_at + datetime.timedelta(seconds=self.store.getHitTimeout())
# timeLeft = (self.timeout - datetime.datetime.utcnow()).total_seconds()
if self.hit.isSubmitted(): if self.hit.isSubmitted():
raise Exception("Opening websocket for already submitted hit") raise Exception("Opening websocket for already submitted hit")
@ -87,7 +90,8 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
#logger.info(f"New client connected: {self.request.remote_ip} for {self.hit.id}/{self.hit.hit_id}") #logger.info(f"New client connected: {self.request.remote_ip} for {self.hit.id}/{self.hit.hit_id}")
self.eventQ.put(Signal('server.open', dict(assignment_id=self.assignment_id))) self.eventQ.put(Signal('server.open', dict(assignment_id=self.assignment_id)))
self.strokes = [] self.strokes = []
# the client sent the message # the client sent the message
def on_message(self, message): def on_message(self, message):
@ -97,7 +101,7 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
logger.critical(f"Skip message for non-last assignment {message}") logger.critical(f"Skip message for non-last assignment {message}")
return return
if datetime.datetime.now() > self.timeout: if datetime.datetime.utcnow() > self.timeout:
logger.critical("Close websocket after timeout (abandon?)") logger.critical("Close websocket after timeout (abandon?)")
self.close() self.close()
return return
@ -164,6 +168,9 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
# client disconnected # client disconnected
def on_close(self): def on_close(self):
self.__class__.rmConnection(self) self.__class__.rmConnection(self)
if self.assignment_id:
self.eventQ.put(Signal('server.close', dict(assignment_id=self.assignment_id, abandoned=self.abandoned)))
logger.info(f"Client disconnected: {self.request.remote_ip}") logger.info(f"Client disconnected: {self.request.remote_ip}")
# TODO: abandon assignment?? # TODO: abandon assignment??
@ -206,6 +213,20 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
if client not in cls.connections: if client not in cls.connections:
return return
cls.connections.remove(client) cls.connections.remove(client)
@classmethod
def hasConnection(cls, client):
return client in cls.connections
@classmethod
def timeoutConnectionForAssignment(cls, assignment_id):
logger.warn(f"Check timeout for {assignment_id}")
for client in cls.connections:
logger.info(client.assignment_id)
if client.assignment_id == assignment_id:
client.abandoned = True
client.close()
class StatusWebSocketHandler(tornado.websocket.WebSocketHandler): class StatusWebSocketHandler(tornado.websocket.WebSocketHandler):
@ -311,6 +332,8 @@ class DrawPageHandler(tornado.web.RequestHandler):
logger.warning(f"Create new assignment {assignmentId}") logger.warning(f"Create new assignment {assignmentId}")
assignment = self.store.newAssignment(self.store.currentHit, assignmentId) assignment = self.store.newAssignment(self.store.currentHit, assignmentId)
self.store.saveAssignment(assignment) self.store.saveAssignment(assignment)
logger.info(f"Set close timeout for {self.store.getHitTimeout()}")
Server.loop.asyncio_loop.call_later(self.store.getHitTimeout(), WebSocketHandler.timeoutConnectionForAssignment, assignment.assignment_id)
previous_hit = self.store.getLastSubmittedHit() previous_hit = self.store.getLastSubmittedHit()
if not previous_hit: if not previous_hit:
@ -432,7 +455,6 @@ class StatusPage():
return [hit.toDict() for hit in hits] return [hit.toDict() for hit in hits]
class Server: class Server:
""" """
Server for HIT -> plotter events Server for HIT -> plotter events

View file

@ -5,11 +5,11 @@
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
id="svg8" width="210mm"
version="1.1"
viewBox="0 0 210 210"
height="210mm" height="210mm"
width="210mm"> viewBox="0 0 210 210"
version="1.1"
id="svg8">
<defs <defs
id="defs2" /> id="defs2" />
<metadata <metadata
@ -25,14 +25,15 @@
</rdf:RDF> </rdf:RDF>
</metadata> </metadata>
<g <g
transform="translate(0,-87)" style="stroke-width:1.52441633"
id="layer1"> id="layer1"
transform="matrix(0.65598879,0,0,0.65598879,44.11553,-86.509667)">
<rect <rect
y="138.32738" style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.52441633;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.75590557;stroke-opacity:1"
x="51.327381"
height="107.34524"
width="107.34524"
id="rect815" id="rect815"
style="fill:none;fill-opacity:1;stroke:white;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.75590557;stroke-opacity:1" /> width="107.34524"
height="107.34524"
x="51.327381"
y="138.32738" />
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -13,7 +13,7 @@
height="180mm" height="180mm"
preserveAspectRatio="none" preserveAspectRatio="none"
id="svg3" id="svg3"
sodipodi:docname="000139.svg" sodipodi:docname="basic_square.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"> inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata <metadata
id="metadata9"> id="metadata9">
@ -37,22 +37,23 @@
guidetolerance="10" guidetolerance="10"
inkscape:pageopacity="0" inkscape:pageopacity="0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:window-width="3836" inkscape:window-width="3840"
inkscape:window-height="2126" inkscape:window-height="2160"
id="namedview5" id="namedview5"
showgrid="false" showgrid="false"
inkscape:zoom="1.3875926" inkscape:zoom="1.3875926"
inkscape:cx="311.32047" inkscape:cx="-14.783892"
inkscape:cy="589.76197" inkscape:cy="589.76197"
inkscape:window-x="2" inkscape:window-x="0"
inkscape:window-y="32" inkscape:window-y="0"
inkscape:window-maximized="1" inkscape:window-maximized="1"
inkscape:current-layer="svg3" /> inkscape:current-layer="svg3"
showguides="false" />
<rect <rect
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.75590557;stroke-opacity:1" style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.75590557;stroke-opacity:1"
id="rect819" id="rect819"
width="306.99152" width="306.99152"
height="306.99152" height="306.99152"
x="1287.0762" x="1287.0762"
y="638.77118" /> y="165.88982" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB