Source code for util.decorators
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#
# Copyright 2009 Glencoe Software, Inc. All Rights Reserved.
# Use is subject to license terms supplied in LICENSE.txt
#
"""
OMERO Decorators
"""
import time
import logging
import traceback
import omero
from functools import wraps
perf_log = logging.getLogger("omero.perf")
[docs]
def perf(func):
""" Decorator for (optionally) printing performance statistics """
def handler(*args, **kwargs):
# Early Exit. Can't do this in up a level
# because logging hasn't been configured yet.
lvl = perf_log.getEffectiveLevel()
if lvl > logging.DEBUG:
return func(*args, **kwargs)
try:
self = args[0]
mod = self.__class__.__module__
cls = self.__class__.__name__
tag = "%s.%s.%s" % (mod, cls, func.__name__)
except:
tag = func.__name__
start = time.time()
try:
rv = func(*args, **kwargs)
return rv
finally:
stop = time.time()
diff = stop - start
startMillis = int(start * 1000)
timeMillis = int(diff * 1000)
perf_log.debug(
"start[%d] time[%d] tag[%s]", startMillis, timeMillis, tag)
handler = wraps(func)(handler)
return handler
__FORMAT = "%-.120s"
__RESULT = " Rslt: " + __FORMAT
__EXCEPT = " Excp: " + __FORMAT
[docs]
def remoted(func):
"""
Decorator for catching any uncaught exception
and converting it to an InternalException
"""
log = logging.getLogger("omero.remote")
def exc_handler(*args, **kwargs):
try:
self = args[0]
log.info(" Meth: %s.%s", self.__class__.__name__, func.__name__)
rv = func(*args, **kwargs)
if log.isEnabledFor(logging.DEBUG):
log.debug(__RESULT, rv)
else:
log.info(__RESULT, type(rv))
return rv
except Exception as e:
log.info(__EXCEPT, e)
if isinstance(e, omero.ServerError):
raise
else:
log.warn(
"%s raised a non-ServerError (%s): %s", func, type(e), e)
msg = traceback.format_exc()
raise omero.InternalException(msg, None, "Internal exception")
exc_handler = wraps(func)(exc_handler)
return exc_handler
[docs]
def locked(func):
""" Decorator for using the self._lock argument of the calling instance """
def with_lock(*args, **kwargs):
self = args[0]
self._lock.acquire()
try:
return func(*args, **kwargs)
finally:
self._lock.release()
with_lock = wraps(func)(with_lock)
return with_lock
[docs]
class TimeIt (object):
"""
Decorator to measure the execution time of a function. Assumes that a
logger global var
is available and is the logger instance from :meth:`logging.getLogger`.
@param level: the level to use for logging
@param name: the name to use when logging, function name is used if None
"""
logger = logging.getLogger('omero.timeit')
def __init__(self, level=logging.DEBUG, name=None):
self._level = level
self._name = name
def __call__(self, func):
def wrapped(*args, **kwargs):
name = self._name or func.__name__
self.logger.log(self._level, "timing %s" % (name))
now = time.time()
rv = func(*args, **kwargs)
self.logger.log(self._level, "timed %s: %f" %
(name, time.time() - now))
return rv
return wrapped
[docs]
def timeit(func):
"""
Shortcut version of the :class:`TimeIt` decorator class.
Logs at logging.DEBUG level.
"""
def wrapped(*args, **kwargs):
TimeIt.logger.log(logging.DEBUG, "timing %s" % (func.__name__))
now = time.time()
rv = func(*args, **kwargs)
TimeIt.logger.log(logging.DEBUG, "timed %s: %f" %
(func.__name__, time.time() - now))
return rv
return TimeIt()(func)
[docs]
def setsessiongroup(func):
"""
For BlitzObjectWrapper class derivate functions,
sets the session group to match the object group.
"""
def wrapped(self, *args, **kwargs):
rev = self._conn.setGroupForSession(
self.getDetails().getGroup().getId())
try:
return func(self, *args, **kwargs)
finally:
if rev:
self._conn.revertGroupForSession()
return wrapped