def graphtxn(write=False, create=False, excl=False, on_success=None, on_failure=None):
def decorator(func):
def wrapper(self, _, uuid, *args, **kwargs):
g = self.graph(uuid, readonly=not write, create=create, excl=excl)
success = None
try:
with g.transaction(write=write) as txn:
lastID = txn.lastID
success = False
ret = func(self, g, txn, _, uuid, *args, **kwargs)
try:
next = getattr(ret, 'next')
except AttributeError:
ret = [ret] if ret is not None else []
finally:
if write:
txn.flush()
self.res.headers.set('X-lg-updates', txn.lastID - lastID)
self.res.headers.set('X-lg-maxID', txn.lastID)
for x in ret:
yield x
success = True
# delay final chunking trailer until txn has been committed
if write:
if 'x-lg-sync' in self.req.headers:
g.sync(force=True)
yield ''
except HTTPError:
raise
except (IOError, OSError) as e:
raise HTTPError(507 if e.errno is errno.ENOSPC else 500, str(e))
except Exception as e:
info = sys.exc_info()
log.error('Unhandled exception: %s', traceback.print_exception(*info))
raise
finally:
if success is True:
if on_success:
on_success(g)
elif success is False:
if on_failure:
on_failure(g)
g.close()
return wrapper
return decorator
评论列表
文章目录