From: Chris Lamb Date: Sat, 31 Oct 2009 12:23:21 +0000 (+0000) Subject: Prefer the "Borg" pattern over the GoF singleton pattern. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b5da3a8242954873807477980107afb3d5d33876;p=dak Prefer the "Borg" pattern over the GoF singleton pattern. The only visible difference is the lack of object identity between instances. Signed-off-by: Chris Lamb --- diff --git a/daklib/config.py b/daklib/config.py index bc16f95a..2d0b8e85 100755 --- a/daklib/config.py +++ b/daklib/config.py @@ -32,8 +32,6 @@ import os import apt_pkg import socket -from singleton import Singleton - ################################################################################ default_config = "/etc/dak/dak.conf" #: default dak config, defines host properties @@ -41,13 +39,20 @@ default_config = "/etc/dak/dak.conf" #: default dak config, defines host propert def which_conf_file(): return os.getenv("DAK_CONFIG", default_config) -class Config(Singleton): +class Config(object): """ A Config object is a singleton containing information about the DAK configuration """ + + __shared_state = {} + def __init__(self, *args, **kwargs): - super(Config, self).__init__(*args, **kwargs) + self.__dict__ = self.__shared_state + + if not getattr(self, 'initialised', False): + self.initialised = True + self._readconf() def _readconf(self): apt_pkg.init() @@ -71,9 +76,6 @@ class Config(Singleton): self.Find = self.Cnf.Find self.FindB = self.Cnf.FindB - def _startup(self, *args, **kwargs): - self._readconf() - def has_key(self, name): return self.Cnf.has_key(name) diff --git a/daklib/dbconn.py b/daklib/dbconn.py index 26191ae2..fd8ab7ca 100755 --- a/daklib/dbconn.py +++ b/daklib/dbconn.py @@ -51,7 +51,6 @@ from sqlalchemy.exc import * from sqlalchemy.orm.exc import NoResultFound from config import Config -from singleton import Singleton from textutils import fix_maintainer ################################################################################ @@ -2502,18 +2501,19 @@ __all__.append('UploadBlock') ################################################################################ -class DBConn(Singleton): +class DBConn(object): """ database module init. """ + __shared_state = {} + def __init__(self, *args, **kwargs): - super(DBConn, self).__init__(*args, **kwargs) + self.__dict__ = self.__shared_state - def _startup(self, *args, **kwargs): - self.debug = False - if kwargs.has_key('debug'): - self.debug = True - self.__createconn() + if not getattr(self, 'initialised', False): + self.initialised = True + self.debug = kwargs.has_key('debug') + self.__createconn() def __setuptables(self): self.tbl_architecture = Table('architecture', self.db_meta, autoload=True) diff --git a/daklib/holding.py b/daklib/holding.py index 0c472d12..b637738a 100755 --- a/daklib/holding.py +++ b/daklib/holding.py @@ -30,19 +30,22 @@ import os from errno import ENOENT, EEXIST, EACCES import shutil -from singleton import Singleton from config import Config from utils import fubar ############################################################################### -class Holding(Singleton): +class Holding(object): + __shared_state = {} + def __init__(self, *args, **kwargs): - super(Holding, self).__init__(*args, **kwargs) + self.__dict__ = self.__shared_state - def _startup(self): - self.in_holding = {} - self.holding_dir = Config()["Dir::Queue::Holding"] + if not getattr(self, 'initialised', False): + self.initialised = True + + self.in_holding = {} + self.holding_dir = Config()["Dir::Queue::Holding"] def copy_to_holding(self, filename): base_filename = os.path.basename(filename) diff --git a/daklib/singleton.py b/daklib/singleton.py deleted file mode 100644 index 535a25a3..00000000 --- a/daklib/singleton.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python -# vim:set et ts=4 sw=4: - -""" -Singleton pattern code - -Inspiration for this very simple ABC was taken from various documents / -tutorials / mailing lists. This may not be thread safe but given that -(as I write) large chunks of dak aren't even type-safe, I'll live with -it for now - -@contact: Debian FTPMaster -@copyright: 2008 Mark Hymers -@license: GNU General Public License version 2 or later -""" - -################################################################################ - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -################################################################################ - -# < sgran> NCommander: in SQL, it's better to join than to repeat information -# < tomv_w> that makes SQL the opposite to Debian mailing lists! - -################################################################################ - -""" -This class set implements objects that may need to be instantiated multiple -times, but we don't want the overhead of actually creating and init'ing -them more than once. It also saves us using globals all over the place -""" - -class Singleton(object): - """This is the ABC for other dak Singleton classes""" - __single = None - def __new__(cls, *args, **kwargs): - # Check to see if a __single exists already for this class - # Compare class types instead of just looking for None so - # that subclasses will create their own __single objects - if cls != type(cls.__single): - cls.__single = object.__new__(cls, *args, **kwargs) - cls.__single._startup(*args, **kwargs) - return cls.__single - - def __init__(self, *args, **kwargs): - if type(self) == "Singleton": - raise NotImplementedError("Singleton is an ABC") - - def _startup(self): - """ - _startup is a private method used instead of __init__ due to the way - we instantiate this object - """ - raise NotImplementedError("Singleton is an ABC") - diff --git a/daklib/summarystats.py b/daklib/summarystats.py index 86300cc9..60702c3d 100755 --- a/daklib/summarystats.py +++ b/daklib/summarystats.py @@ -26,16 +26,15 @@ Simple summary class for dak ############################################################################### -from singleton import Singleton +class SummaryStats(object): + __shared_state = {} -############################################################################### - -class SummaryStats(Singleton): def __init__(self, *args, **kwargs): - super(SummaryStats, self).__init__(*args, **kwargs) + self.__dict__ = self.__shared_state - def _startup(self): - self.reset_accept() + if not getattr(self, 'initialised', False): + self.initialised = True + self.reset_accept() def reset_accept(self): self.accept_count = 0 diff --git a/daklib/urgencylog.py b/daklib/urgencylog.py index fb2e7fab..7d679058 100755 --- a/daklib/urgencylog.py +++ b/daklib/urgencylog.py @@ -29,33 +29,35 @@ Urgency Logger class for dak import os import time -from singleton import Singleton from config import Config from utils import warn, open_file, move ############################################################################### -class UrgencyLog(Singleton): +class UrgencyLog(object): "Urgency Logger object" + + __shared_state = {} + def __init__(self, *args, **kwargs): - super(UrgencyLog, self).__init__(*args, **kwargs) + self.__dict__ = self.__shared_state - def _startup(self): - "Initialize a new Urgency Logger object" + if not getattr(self, 'initialised', False): + self.initialised = True - self.timestamp = time.strftime("%Y%m%d%H%M%S") + self.timestamp = time.strftime("%Y%m%d%H%M%S") - # Create the log directory if it doesn't exist - self.log_dir = Config()["Dir::UrgencyLog"] + # Create the log directory if it doesn't exist + self.log_dir = Config()["Dir::UrgencyLog"] - if not os.path.exists(self.log_dir) or not os.access(self.log_dir, os.W_OK): - warn("UrgencyLog directory %s does not exist or is not writeable, using /srv/ftp.debian.org/tmp/ instead" % (self.log_dir)) - self.log_dir = '/srv/ftp.debian.org/tmp/' + if not os.path.exists(self.log_dir) or not os.access(self.log_dir, os.W_OK): + warn("UrgencyLog directory %s does not exist or is not writeable, using /srv/ftp.debian.org/tmp/ instead" % (self.log_dir)) + self.log_dir = '/srv/ftp.debian.org/tmp/' - # Open the logfile - self.log_filename = "%s/.install-urgencies-%s.new" % (self.log_dir, self.timestamp) - self.log_file = open_file(self.log_filename, 'w') - self.writes = 0 + # Open the logfile + self.log_filename = "%s/.install-urgencies-%s.new" % (self.log_dir, self.timestamp) + self.log_file = open_file(self.log_filename, 'w') + self.writes = 0 def log(self, source, version, urgency): "Log an event"