summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Ronacher <armin.ronacher@active-4.com>2016-04-22 20:01:16 +0200
committerArmin Ronacher <armin.ronacher@active-4.com>2016-04-22 23:47:15 +0200
commit4e376bdc6fe829c264d0ae69d7de00497ffe1e1f (patch)
tree7f18f37e6e7109c01824a98223ea0343777d3082
parented9dfc30944ad52be35d4375b450da710b29b03f (diff)
downloadraven-4e376bdc6fe829c264d0ae69d7de00497ffe1e1f.tar.gz
Add @once decorator instead of custom hackery in breadcrumbs
-rw-r--r--raven/breadcrumbs.py19
-rw-r--r--raven/utils/__init__.py21
2 files changed, 27 insertions, 13 deletions
diff --git a/raven/breadcrumbs.py b/raven/breadcrumbs.py
index 1d8b152..c8b1331 100644
--- a/raven/breadcrumbs.py
+++ b/raven/breadcrumbs.py
@@ -1,13 +1,9 @@
import time
import logging
-from threading import Lock
from types import FunctionType
from raven._compat import iteritems, get_code, text_type
-
-
-_logging_lock = Lock()
-_logging_hooked = False
+from raven.utils import once
class BreadcrumbBuffer(object):
@@ -149,15 +145,12 @@ def _patch_logger():
logging.Logger.log)
+@once
def install_logging_hook():
- global _logging_hooked
- if _logging_hooked:
- return
- with _logging_lock:
- if _logging_hooked:
- return
- _patch_logger()
- _logging_hooked = True
+ """Installs the logging hook if it was not installed yet. Otherwise
+ does nothing.
+ """
+ _patch_logger()
import raven.context
diff --git a/raven/utils/__init__.py b/raven/utils/__init__.py
index 63f1b81..c22f0bc 100644
--- a/raven/utils/__init__.py
+++ b/raven/utils/__init__.py
@@ -9,6 +9,8 @@ from __future__ import absolute_import
from raven._compat import iteritems, string_types
import logging
+import threading
+from functools import update_wrapper
try:
import pkg_resources
except ImportError:
@@ -167,3 +169,22 @@ class memoize(object):
if n not in d:
d[n] = self.func(obj)
return d[n]
+
+
+def once(func):
+ """Runs a thing once and once only."""
+ lock = threading.Lock()
+
+ def new_func(*args, **kwargs):
+ if new_func.called:
+ return
+ with lock:
+ if new_func.called:
+ return
+ rv = func(*args, **kwargs)
+ new_func.called = True
+ return rv
+
+ new_func = update_wrapper(new_func, func)
+ new_func.called = False
+ return new_func