Skip to content
Snippets Groups Projects
Commit 0d3f54d6 authored by Patrick Jentsch's avatar Patrick Jentsch
Browse files

Implement JSON patches for corpus and job lists.

parent 98de5811
No related branches found
No related tags found
No related merge requests found
...@@ -4,20 +4,22 @@ from flask_socketio import send ...@@ -4,20 +4,22 @@ from flask_socketio import send
from .. import create_app, db, socketio from .. import create_app, db, socketio
from ..models import User from ..models import User
import json import json
import jsonpatch
import os import os
stop = [] '''
' A list containing session ids of disconnected Socket.IO sessions. It is used
' to signal associated background tasks to stop.
'''
disconnected = []
@socketio.on('connect') @socketio.on('connect')
@login_required @login_required
def connect(): def connect():
print('{} connected'.format(current_user.username)) # print('{} connected'.format(current_user.username))
send('You entered the room {}'.format(request.sid), # send('You entered the room {}'.format(request.sid),
room=request.sid) # room=request.sid)
if request.sid in stop:
stop.remove(request.sid)
socketio.start_background_task(background_task, socketio.start_background_task(background_task,
current_user.id, current_user.id,
request.sid) request.sid)
...@@ -26,52 +28,55 @@ def connect(): ...@@ -26,52 +28,55 @@ def connect():
@socketio.on('disconnect') @socketio.on('disconnect')
@login_required @login_required
def disconnect(): def disconnect():
stop.append(request.sid) disconnected.append(request.sid)
print('{} disconnected'.format(current_user.username)) #print('{} disconnected'.format(current_user.username))
def background_task(user_id, session_id): def background_task(user_id, session_id):
''' '''
' Check user jobs every 3 seconds and emit a json patch on change ' Sends initial corpus and job lists to the client. Afterwards it checks
' every 3 seconds if changes to the initial values appeared. If changes are
' detected, a RFC 6902 compliant JSON patch gets send.
'
' NOTE: The initial values are send as a init-* events.
' The JSON patches are send as update-* events.
''' '''
app = create_app(os.getenv('FLASK_CONFIG') or 'default', main=False) app = create_app(os.getenv('FLASK_CONFIG') or 'default', main=False)
corpora = []
jobs = []
with app.app_context(): with app.app_context():
user = db.session.query(User).filter_by(id=user_id).first() user = db.session.query(User).filter_by(id=user_id).first()
for corpus in user.corpora: ''' Get current values from the database. '''
corpora.append(corpus.to_dict()) corpora = list(map(lambda x: x.to_dict(), user.corpora))
jobs = list(map(lambda x: x.to_dict(), user.jobs))
''' Send initial values. '''
socketio.emit('init-corpora', socketio.emit('init-corpora',
{'data': json.dumps(corpora)}, {'data': json.dumps(corpora)},
room=session_id) room=session_id)
for job in user.jobs:
jobs.append(job.to_dict())
socketio.emit('init-jobs', socketio.emit('init-jobs',
{'data': json.dumps(jobs)}, {'data': json.dumps(jobs)},
room=session_id) room=session_id)
while True: ''' TODO: Implement maximum runtime for this loop. '''
if session_id in stop: while session_id not in disconnected:
break
print(session_id + ' running') print(session_id + ' running')
socketio.emit('message', 'heartbeat', room=session_id) # socketio.emit('message', 'heartbeat', room=session_id)
''' Get current values from the database '''
new_corpora = [] new_corpora = list(map(lambda x: x.to_dict(), user.corpora))
new_jobs = [] new_jobs = list(map(lambda x: x.to_dict(), user.jobs))
for corpus in user.corpora: ''' Compute JSON patches. '''
new_corpora.append(corpus.to_dict()) corpus_patch = jsonpatch.JsonPatch.from_diff(corpora, new_corpora)
for job in user.jobs: jobs_patch = jsonpatch.JsonPatch.from_diff(jobs, new_jobs)
new_jobs.append(job.to_dict()) ''' In case there are patches, send them to the user. '''
if corpus_patch:
# socketio.send('new_corpora: ' + json.dumps(new_corpora), room=session_id) socketio.emit('update-corpora',
# socketio.send('new_jobs: ' + json.dumps(new_jobs), room=session_id) corpus_patch.to_string(),
# TODO: calculate json patch: new_corpora <-> corpora room=session_id)
# TODO: calculate json patch: new_jobs <-> jobs if jobs_patch:
# socketio.emit('update-corpora', {data: corpora_patch}, room=session_id) socketio.emit('update-jobs',
# socketio.emit('update-jobs', {data: jobs_patch}, room=session_id) jobs_patch.to_string(),
room=session_id)
''' Set new values as a reference for the next iteration. '''
corpora = new_corpora corpora = new_corpora
jobs = new_jobs jobs = new_jobs
socketio.sleep(3) socketio.sleep(3)
# TODO: Implement maximum runtime for this thread. disconnected.remove(session_id)
print(session_id + ' stopped') # print(session_id + ' stopped')
...@@ -9,5 +9,6 @@ Flask-SocketIO ...@@ -9,5 +9,6 @@ Flask-SocketIO
Flask-SQLAlchemy Flask-SQLAlchemy
Flask-Table Flask-Table
Flask-WTF Flask-WTF
jsonpatch
python-dotenv python-dotenv
redis redis
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment