use proper transactions
This commit is contained in:
parent
08cb3cd324
commit
c9333adc5c
@ -180,7 +180,7 @@ def make_app(conf):
|
|||||||
if uwsgi is not None:
|
if uwsgi is not None:
|
||||||
cacheobj = cache.uWSGICache(timeout=3600)
|
cacheobj = cache.uWSGICache(timeout=3600)
|
||||||
else:
|
else:
|
||||||
cacheobj = cache.SACache(dbobj, threshold=2048)
|
cacheobj = cache.SACache(conf.get("general", "dbpath"), threshold=2048)
|
||||||
|
|
||||||
jobs = tasks.Jobs()
|
jobs = tasks.Jobs()
|
||||||
jobs.register("db-purge", dbobj, conf.getint("moderation", "purge-after"))
|
jobs.register("db-purge", dbobj, conf.getint("moderation", "purge-after"))
|
||||||
|
87
isso/cache/sa.py
vendored
87
isso/cache/sa.py
vendored
@ -4,64 +4,79 @@ from __future__ import absolute_import, unicode_literals
|
|||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from sqlalchemy import Table, Column, MetaData, create_engine
|
||||||
|
from sqlalchemy import Float, String, LargeBinary
|
||||||
from sqlalchemy.sql import select, func
|
from sqlalchemy.sql import select, func
|
||||||
|
|
||||||
from . import Base
|
from . import Base
|
||||||
|
|
||||||
|
|
||||||
class SACache(Base):
|
def get(con, cache, key):
|
||||||
"""Implements cache using SQLAlchemy Core.
|
rv = con.execute(
|
||||||
|
select([cache.c.value]).where(
|
||||||
JSON is used for safe serialization of python primitives.
|
cache.c.key == key)).fetchone()
|
||||||
"""
|
|
||||||
|
|
||||||
serialize = True
|
|
||||||
|
|
||||||
def __init__(self, db, threshold=1024, timeout=-1):
|
|
||||||
super(SACache, self).__init__(threshold, timeout)
|
|
||||||
self.db = db
|
|
||||||
|
|
||||||
def _get(self, ns, key):
|
|
||||||
rv = self.db.engine.execute(
|
|
||||||
select([self.db.cache.c.value]).where(
|
|
||||||
self.db.cache.c.key == ns + b'-' + key)).fetchone()
|
|
||||||
|
|
||||||
if rv is None:
|
if rv is None:
|
||||||
raise KeyError
|
raise KeyError
|
||||||
|
|
||||||
return rv[0]
|
return rv[0]
|
||||||
|
|
||||||
def _set(self, ns, key, value):
|
|
||||||
with self.db.transaction:
|
|
||||||
cnt = self.db.engine.execute(
|
|
||||||
select([func.count(self.db.cache)])).fetchone()[0]
|
|
||||||
|
|
||||||
if cnt + 1 > self.threshold:
|
def set(con, cache, key, value, threshold):
|
||||||
self.db.engine.execute(
|
cnt = con.execute(
|
||||||
self.db.cache.delete().where(
|
select([func.count(cache)])).fetchone()[0]
|
||||||
self.db.cache.c.key.in_(select(
|
|
||||||
[self.db.cache.c.key])
|
if cnt + 1 > threshold:
|
||||||
.order_by(self.db.cache.c.time)
|
con.execute(
|
||||||
|
cache.delete().where(
|
||||||
|
cache.c.key.in_(select(
|
||||||
|
[cache.c.key])
|
||||||
|
.order_by(cache.c.time)
|
||||||
.limit(1))))
|
.limit(1))))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._get(ns, key)
|
get(con, cache, key)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
insert = True
|
insert = True
|
||||||
else:
|
else:
|
||||||
insert = False
|
insert = False
|
||||||
|
|
||||||
if insert:
|
if insert:
|
||||||
stmt = self.db.cache.insert().values(
|
stmt = cache.insert().values(key=key, value=value, time=time.time())
|
||||||
key=ns + b'-' + key, value=value, time=time.time())
|
|
||||||
else:
|
else:
|
||||||
stmt = self.db.cache.update().values(
|
stmt = cache.update().values(value=value, time=time.time()) \
|
||||||
value=value, time=time.time()).where(
|
.where(cache.c.key == key)
|
||||||
self.db.cache.c.key == ns + b'-' + key)
|
|
||||||
|
|
||||||
self.db.engine.execute(stmt)
|
con.execute(stmt)
|
||||||
|
|
||||||
|
|
||||||
|
def delete(con, cache, key):
|
||||||
|
con.execute(cache.delete(cache.c.key == key))
|
||||||
|
|
||||||
|
|
||||||
|
class SACache(Base):
|
||||||
|
"""Implements cache using SQLAlchemy Core.
|
||||||
|
"""
|
||||||
|
|
||||||
|
serialize = True
|
||||||
|
|
||||||
|
def __init__(self, db, threshold=1024, timeout=-1):
|
||||||
|
super(SACache, self).__init__(threshold, timeout)
|
||||||
|
self.metadata = MetaData()
|
||||||
|
self.engine = create_engine(db)
|
||||||
|
|
||||||
|
self.cache = Table("cache", self.metadata,
|
||||||
|
Column("key", String(255), primary_key=True),
|
||||||
|
Column("value", LargeBinary(65535)),
|
||||||
|
Column("time", Float))
|
||||||
|
|
||||||
|
self.metadata.create_all(self.engine)
|
||||||
|
|
||||||
|
def _get(self, ns, key):
|
||||||
|
return get(self.engine.connect(), self.cache, ns + b'-' + key)
|
||||||
|
|
||||||
|
def _set(self, ns, key, value):
|
||||||
|
set(self.engine.connect(), self.cache, ns + b'-' + key, value, self.threshold)
|
||||||
|
|
||||||
def _delete(self, ns, key):
|
def _delete(self, ns, key):
|
||||||
with self.db.transaction:
|
delete(self.engine.connect(), self.cache, ns + b'-' + key)
|
||||||
self.db.engine.execute(
|
|
||||||
self.db.cache.delete(self.db.cache.c.key == ns + b'-' + key))
|
|
||||||
|
@ -52,10 +52,6 @@ class Adapter(object):
|
|||||||
Column("key", String(255), primary_key=True),
|
Column("key", String(255), primary_key=True),
|
||||||
Column("value", String(255)))
|
Column("value", String(255)))
|
||||||
|
|
||||||
self.cache = Table("cache", self.metadata,
|
|
||||||
Column("key", String(255), primary_key=True),
|
|
||||||
Column("value", LargeBinary(65535)),
|
|
||||||
Column("time", Float))
|
|
||||||
|
|
||||||
self.metadata.create_all(self.engine)
|
self.metadata.create_all(self.engine)
|
||||||
self.preferences = Preferences(self.engine, preferences)
|
self.preferences = Preferences(self.engine, preferences)
|
||||||
|
Loading…
Reference in New Issue
Block a user