Commit df3e9282 by Gustav Arngården

Merge pull request #3 from git2samus/inyection_logger

Injection logger
parents f580ed27 1c902435
...@@ -2,31 +2,18 @@ ...@@ -2,31 +2,18 @@
import time import time
import pymongo import pymongo
def get_methods(obj): def get_methods(*objs):
attrs = (attr for attr in dir(obj)) return set(
attrs = (attr for attr in attrs if not attr.startswith('_')) attr
return set([attr for attr in attrs if hasattr(getattr(obj, attr), '__call__')]) for obj in objs
for attr in dir(obj)
if not attr.startswith('_')
and hasattr(getattr(obj, attr), '__call__')
)
EXECUTABLE_MONGO_METHODS = get_methods(pymongo.collection.Collection) EXECUTABLE_MONGO_METHODS = get_methods(pymongo.collection.Collection,
EXECUTABLE_MONGO_METHODS.update(get_methods(pymongo.Connection)) pymongo.Connection,
EXECUTABLE_MONGO_METHODS.update(get_methods(pymongo)) pymongo)
def safe_mongocall(call):
""" Decorator for automatic handling of AutoReconnect-exceptions.
"""
def _safe_mongocall(*args, **kwargs):
for i in xrange(4):
try:
return call(*args, **kwargs)
except pymongo.errors.AutoReconnect:
print 'AutoReconnecting, try %d' % i
time.sleep(pow(2, i))
# Try one more time, but this time, if it fails, let the
# exception bubble up to the caller.
return call(*args, **kwargs)
return _safe_mongocall
class Executable: class Executable:
...@@ -34,11 +21,21 @@ class Executable: ...@@ -34,11 +21,21 @@ class Executable:
using the safe_mongocall decorator. using the safe_mongocall decorator.
""" """
def __init__(self, method): def __init__(self, method, logger):
self.method = method self.method = method
self.logger = logger
@safe_mongocall
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
""" Automatic handling of AutoReconnect-exceptions.
"""
for i in xrange(4):
try:
return self.method(*args, **kwargs)
except pymongo.errors.AutoReconnect:
self.logger.warning('AutoReconnecting, try %d' % i)
time.sleep(pow(2, i))
# Try one more time, but this time, if it fails, let the
# exception bubble up to the caller.
return self.method(*args, **kwargs) return self.method(*args, **kwargs)
def __dir__(self): def __dir__(self):
...@@ -56,16 +53,22 @@ class MongoProxy: ...@@ -56,16 +53,22 @@ class MongoProxy:
Executable-instance that handles AutoReconnect-exceptions transparently. Executable-instance that handles AutoReconnect-exceptions transparently.
""" """
def __init__(self, conn): def __init__(self, conn, logger=None):
""" conn is an ordinary MongoDB-connection. """ conn is an ordinary MongoDB-connection.
""" """
if logger is None:
import logging
logger = logging.getLogger(__name__)
self.conn = conn self.conn = conn
self.logger = logger
def __getitem__(self, key): def __getitem__(self, key):
""" Create and return proxy around the method in the connection """ Create and return proxy around the method in the connection
named "key". named "key".
""" """
item = self.conn[key] item = self.conn[key]
if hasattr(item, '__call__'): if hasattr(item, '__call__'):
...@@ -78,10 +81,10 @@ class MongoProxy: ...@@ -78,10 +81,10 @@ class MongoProxy:
handles AutoReconnect-Exception. handles AutoReconnect-Exception.
""" """
attr = getattr(self.conn, key) attr = getattr(self.conn, key)
if hasattr(attr, '__call__') and key in EXECUTABLE_MONGO_METHODS: if hasattr(attr, '__call__') and key in EXECUTABLE_MONGO_METHODS:
return Executable(attr) return Executable(attr, self.logger)
return attr return attr
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment