]> git.decadent.org.uk Git - dak.git/commitdiff
Prefer the "Borg" pattern over the GoF singleton pattern.
authorChris Lamb <lamby@debian.org>
Sat, 31 Oct 2009 12:23:21 +0000 (12:23 +0000)
committerChris Lamb <lamby@debian.org>
Sat, 31 Oct 2009 23:00:13 +0000 (23:00 +0000)
The only visible difference is the lack of object identity between
instances.

Signed-off-by: Chris Lamb <lamby@debian.org>
daklib/config.py
daklib/dbconn.py
daklib/holding.py
daklib/singleton.py [deleted file]
daklib/summarystats.py
daklib/urgencylog.py

index bc16f95a7c74f4496da10244984eadd248d531b0..2d0b8e851d7df11db3dd1bba146651b732548b49 100755 (executable)
@@ -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)
 
index 26191ae273aa71a4f0ed09ca52044d438cedc451..fd8ab7caa9f467c19c70026184d49c5f7dfad892 100755 (executable)
@@ -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)
index 0c472d120f6b07b256cfc1af065aca7a753526dd..b637738a5af73d86f1b978137727407d7d9bcf5c 100755 (executable)
@@ -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 (file)
index 535a25a..0000000
+++ /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 <ftpmaster@debian.org>
-@copyright: 2008  Mark Hymers <mhy@debian.org>
-@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")
-
index 86300cc9a251aafed14866f92c825aa88f5cd5de..60702c3d10d3535de7df32cebe1e7a9ea5df95a9 100755 (executable)
@@ -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
index fb2e7fab7363b459182616526045c793d9dd4648..7d679058ee4bc6799d372086dfad0c43904ff714 100755 (executable)
@@ -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"