Package Products :: Package ZenEvents :: Module DbConnectionPool |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenEvents.DbConnectionPool

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2007, Zenoss Inc.
      5  #
      6  # This program is free software; you can redistribute it and/or modify it
      7  # under the terms of the GNU General Public License version 2 as published by
      8  # the Free Software Foundation.
      9  #
     10  # For complete information please visit: http://www.zenoss.com/oss/
     11  #
     12  ###########################################################################
     13  from Exceptions import MySQLConnectionError
     14
     15  import time
     16  import DateTime
     17
     18  from Queue import Queue, Empty, Full
     19
     20  import logging
     21  log = logging.getLogger("zen.DbConnectionPool")
     22
     23  POOL_SIZE = 5
     24  KEEP_ALIVE = 28800
     25
     26 -class DbConnectionPool:
     27
     28 -    def __new__(self):                  # self is a type
     29          if not '_the_instance' in self.__dict__:
     30              self._the_instance = object.__new__(self)
     31          return self._the_instance
     32
     33      '''
     34      instance = None
     35      def __new__(cls, *args, **kargs):
     36          if cls.instance is None:
     37              cls.instance = object.__new__(cls, *args, **kargs)
     38          log.debug('Returning single instance of DbConnectionPool')
     39          return cls.instance
     40      '''
     41
     42 -    def __init__(self):
     43          self.q = Queue(POOL_SIZE)
     44
     45 -    def qsize(self):
     46          return self.q.qsize()
     47
     48 -    def get(self, host=None, port=None, username=None,
     49              password=None, database=None, block=0):
     50          try:
     51              putstamp,obj = self.q.get(block)
     52
     53              if time.time() - putstamp >= KEEP_ALIVE:
     54                  log.debug('Retrieved a stale connection; Pool size: %s' % self.qsize())
     55                  obj.close()
     56                  return self._createConnection(host=host, port=port,
     57                                              username=username,
     58                                              password=password,
     59                                              database=database)
     60              else:
     61                  log.debug('Retrieved a connection; Pool size: %s' % self.qsize())
     62                  if hasattr(obj, 'ping'):
     63                      # maybe the connection timed out: reconnect if necessary
     64                      obj.ping()
     65                  return obj
     66
     67          except Empty:
     68              return self._createConnection(host=host, port=port,
     69                                          username=username,
     70                                          password=password,
     71                                          database=database)
     72
     73 -    def put(self, obj, block=0):
     74          try:
     75              self.q.put((time.time(),obj), block)
     76              log.debug('Returned a connection; Pool size: %s' % self.qsize())
     77          except Full:
     78              pass
     79
     80 -    def _createConnection(self, host=None, port=None,
     81                          username=None, password=None, database=None):
     82          # These MySQLdb imports were moved from the top of the file to
     83          # here to avoid importing MySQLdb libs at startup.  This is
     84          # desirable for DistributedCollector where we are usually
     85          # executing on a remote box that may not have mysql libs around.
     86          import MySQLdb
     87          import MySQLdb.converters
     88          from MySQLdb.constants import FIELD_TYPE
     89          log.debug('Creating a new connection; Pool size: %s' % self.qsize())
     90          conn = None
     91          mysqlconv = MySQLdb.converters.conversions.copy()
     92          mysqlconv[FIELD_TYPE.DATETIME] = DateTime.DateTime
     93          mysqlconv[FIELD_TYPE.TIMESTAMP] = DateTime.DateTime
     94          # FIXME for some reason it thinks my int is a long -EAD
     95          mysqlconv[FIELD_TYPE.LONG] = int
     96          if not host:
     97              host, database = database, 'events'
     98          if port:
     99              port = int(port)
    100          try:
    101              conn = MySQLdb.connect(host=host, user=username,
    102                                     port=port, passwd=password,
    103                                     db=database, conv=mysqlconv, reconnect=1)
    104              conn.autocommit(1)
    105              return conn
    106          except Exception, e:
    107              raise MySQLConnectionError(str(e))
    108