Web applications
data persistence:
case study for MXCuBE 3
8th MXCuBE meeting, 27 & 28th June 2016 - EMBL, Hamburg - Germany
Matias Guijarro
Software Engineer @ Beamline Control Unit
European Synchrotron Radiation Facility
Grenoble, France
What is web applications data persistence ?
Capability of remembering a state
Tracking state changes across different periods of time
2 approaches : server-side or client-side
Server-side persistence
Session + authentication cookie
Server-side persistence
Session on server
Authentication cookie
Client-side persistence
Why storing data on the client ?
Client-side persistence
HTML5 Web Storage
Up to 10 MB (only a few KB for cookies)
(key, value) pairs, strings only : needs serialization
Client-side persistence
LocalStorage API
setItem(key, value)
getItem(key)
removeItem(key)
clear()
Storage event
Data and state persistence in MXCuBE 3
What do we need to achieve ?
User session in MXCuBE 3
from flask import session
...
@mxcube.route("/mxcube/api/v0.1/login", methods=["POST"])
def login():
content = request.get_json()
loginID = content['proposal']
password = content['password']
loginRes = mxcube.db_connection.login(loginID, password)
if loginRes['status']['code'] == 'ok':
session['loginInfo'] = { 'loginID': loginID, 'password': password, 'loginRes': loginRes }
...
@mxcube.route("/mxcube/api/v0.1/signout")
def signout():
session.clear()
...
from flask import Flask
from flask.ext.session import Session
...
app = Flask(__name__, static_url_path='')
app.config['SESSION_TYPE'] = "redis"
app.config['SESSION_KEY_PREFIX'] = "mxcube:session:"
sess = Session()
sess.init_app(app)
User session in MXCuBE 3, auto login
The session cookie has no expiry date on the client
When MXCuBE 3 application loads, login_info route is called: the client sends its cookie (if it exists), MXCuBE server can decide to do auto login or to close the session
mxcube.route("/mxcube/api/v0.1/login_info", methods=["GET"])
def loginInfo():
loginInfo = session.get("loginInfo")
if loginInfo is not None:
# for the moment, we always do auto login if a client cookie is set ;
# of course, it needs more logic before going production-ready
loginInfo["loginRes"] = mxcube.db_connection.login(loginInfo["loginID"], loginInfo["password"])
session['loginInfo'] = loginInfo
return jsonify({ "synchrotron_name": mxcube.session.synchrotron_name,
"beamline_name": mxcube.session.beamline_name,
"loginType": mxcube.db_connection.loginType.title(),
"loginRes": convert_to_dict(loginInfo["loginRes"] if loginInfo is not None else {}) })
User Interface state persistence in MXCuBE 3
What do we want to persist from UI ?
What we cannot persist
synchronisation with server needed
User Interface state persistence in MXCuBE 3
Proposal: client-side-first persistence
Why ?
Client-side persistence in MXCuBE 3 with redux-persist
Store enhancer for redux
import {persistStore, autoRehydrate} from 'redux-persist'
const store = createStore(reducer, undefined, autoRehydrate())
persistStore(store)
Basic usage involves adding 3 lines to the application
Client-side persistence in MXCuBE 3 with redux-persist
Auto-rehydration works
Possibility to have a fine-grained control thanks to the REHYDRATE action
Do not miraculously solves all persistence problems, but helps a lot
State persistence in MXCuBE 3:
tentative use cases and expected behaviour
1. User reloads page when no queue is running
2. User reloads or closes page while a queue is running
3. User logs out
4. Same user opens another instance of the application from the same computer (e.g from another tab)
5. Same user opens another instance of the application from another computer
6. Another user opens another instance of the application from another computer
Thanks for your attention
Questions ?