improve db sessions for mysql

This commit is contained in:
ziirish 2017-02-20 14:56:52 +01:00
parent 16d80d5d39
commit 6ae56ee268
8 changed files with 74 additions and 22 deletions

View file

@ -237,8 +237,11 @@ def cleanup_restore():
if os.path.isfile(path):
os.unlink(path)
finally:
db.session.delete(rec)
db.session.commit()
try:
db.session.delete(rec)
db.session.commit()
except:
db.session.rollback()
task.revoke()
@ -298,7 +301,10 @@ def perform_restore(self, client, backup,
curr = Task.query.filter_by(uuid=self.request.id).first()
if curr:
curr.expire = datetime.utcnow() + expire
db.session.commit()
try:
db.session.commit()
except:
db.session.rollback()
if err:
# make the task crash
@ -374,8 +380,11 @@ class AsyncRestoreStatus(Resource):
if db:
rec = Task.query.filter_by(uuid=task_id).first()
if rec:
db.session.delete(rec)
db.session.commit()
try:
db.session.delete(rec)
db.session.commit()
except:
db.session.rollback()
task.revoke()
err = str(task.result)
self.abort(502, err)
@ -440,8 +449,11 @@ class AsyncGetFile(Resource):
if db:
rec = Task.query.filter_by(uuid=task_id).first()
if rec:
db.session.delete(rec)
db.session.commit()
try:
db.session.delete(rec)
db.session.commit()
except:
db.session.rollback()
task.revoke()
if dst_server:
@ -636,8 +648,11 @@ class AsyncRestore(Resource):
self.username,
timedelta(minutes=60)
)
db.session.add(db_task)
db.session.commit()
try:
db.session.add(db_task)
db.session.commit()
except:
db.session.rollback()
return {'id': task.id, 'name': 'perform_restore'}, 202

View file

@ -10,6 +10,7 @@
from six import viewkeys
from flask import session, current_app, request
from flask_login import current_user
from werkzeug.datastructures import MultiDict
from . import api
from ..server import BUIServer # noqa
@ -69,15 +70,23 @@ class PrefsUI(Resource):
elif val:
pref = Pref(self.username, key, val)
db.session.add(pref)
db.session.commit()
try:
db.session.commit()
except:
db.session.rollback()
def _update_prefs(self):
"""update prefs"""
args = self.parser.parse_args()
sess = session
ret = {}
req = MultiDict()
for loc in ['values', 'json']:
data = getattr(request, loc, None)
if data:
req.update(data)
for key in viewkeys(args):
if key not in request.values and key not in request.json:
if key not in req:
continue
temp = args.get(key)
if key == 'language':
@ -148,8 +157,14 @@ class PrefsUI(Resource):
if bui.config['WITH_SQL']:
from ..ext.sql import db
from ..models import Pref
Pref.query.filter_by(user=self.username, key=key).delete()
db.session.commit()
try:
Pref.query.filter_by(
user=self.username,
key=key
).delete()
db.session.commit()
except:
db.session.rollback()
ret[key] = sess.get(key)
return ret

View file

@ -332,6 +332,10 @@ def create_app(conf=None, verbose=0, logfile=None, **kwargs):
app.config['REMEMBER_COOKIE_HTTPONLY'] = True
# optimize SQL pools for MySQL driver
app.config['SQLALCHEMY_POOL_SIZE'] = 20
app.config['SQLALCHEMY_POOL_RECYCLE'] = 600
if debug and not gunicorn: # pragma: no cover
app.config['DEBUG'] = True and not unittest
app.config['TESTING'] = True and not unittest

View file

@ -119,7 +119,10 @@ class UserHandler(BUIuser):
else:
pref = Pref(self.name, 'language', self.language)
db.session.add(pref)
db.session.commit()
try:
db.session.commit()
except:
db.session.rollback()
def refresh_session(self):
self.authenticated = session.get('authenticated', False)

View file

@ -52,8 +52,12 @@ class SessionManager(object):
self.invalidate_current_session()
else:
self.invalidate_session_by_id(id)
db.session.delete(store)
db.session.commit()
try:
db.session.delete(store)
db.session.commit()
except:
db.session.rollback()
return False
return True
elif store:
ip = self.anonym_ip(request.remote_addr)
@ -96,8 +100,11 @@ class SessionManager(object):
remember,
api
)
db.session.add(store)
db.session.commit()
try:
db.session.add(store)
db.session.commit()
except:
db.session.rollback()
session['persistent'] = remember
def session_in_db(self):
@ -118,8 +125,11 @@ class SessionManager(object):
if self.session_managed():
from .ext.sql import db
from .models import Session
Session.query.filter_by(uuid=id).delete()
db.session.commit()
try:
Session.query.filter_by(uuid=id).delete()
db.session.commit()
except:
db.session.rollback()
def get_session_username(self):
"""Return the username stored in the current session"""

View file

@ -78,6 +78,9 @@ worker_class = 'gevent'
worker_connections = 1000
timeout = 300
keepalive = 2
# Set this to False when using a MySQL database because the MySQL driver does
# not play nicely with concurrency
preload = True
#

View file

@ -2,11 +2,10 @@ CONFIG = {
'args': (
'--bind=0.0.0.0:5000',
'--user=burpui',
'--preload',
'--workers=5',
'--worker-class=gevent',
'--access-logfile=/var/log/gunicorn/burp-ui_access.log',
'--error-logfile=/var/log/gunicorn/burp-ui_error.log',
'burpui:create_app(logfile="/var/log/gunicorn/burp-ui_info.log")',
'burpui:create_app(logfile="/var/log/gunicorn/burp-ui_info.log",verbose=2)',
),
}

View file

@ -88,6 +88,9 @@ instance:
pip install mysqlclient
.. warning:: The MySQL driver does not seem to play nicely with concurrency, you
should set ``preload=False`` within your gunicorn config.
Limiter
-------