Commit a16063bb by Jiri Techet

Use different singleton pattern to support inheritance

The previous singleton pattern doesn't work when a class is inherited from the GeoIP class
and causes creation of a new GeoIP object every time GeoIP is accessed. In addition add
locks to protect from multiple instance creation from different threads.
parent 6e94f20b
......@@ -51,33 +51,36 @@ MEMORY_CACHE = const.MEMORY_CACHE
ENCODING = const.ENCODING
class GeoIPError(Exception):
pass
class _GeoIPMetaclass(type):
def __new__(cls, *args, **kwargs):
_instances = {}
_instance_lock = Lock()
def __call__(cls, *args, **kwargs):
""" Singleton method to gets an instance without reparsing
the database, the filename is being used as cache key.
"""
if not hasattr(cls, '_instances'):
cls._instances = {}
if len(args) > 0:
filename = args[0]
elif 'filename' in kwargs:
filename = kwargs['filename']
else:
return None
cls._instance_lock.acquire()
if filename not in cls._instances:
cls._instances[filename] = type.__new__(cls, *args, **kwargs)
cls._instances[filename] = super(_GeoIPMetaclass, cls).__call__(*args, **kwargs)
cls._instance_lock.release()
return cls._instances[filename]
_GeoIPBase = _GeoIPMetaclass('GeoIPBase', (object,), {})
class GeoIPError(Exception):
pass
class GeoIP(object):
__metaclass__ = _GeoIPMetaclass
class GeoIP(_GeoIPBase):
def __init__(self, filename, flags=0):
"""
Initialize the class.
......
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