cubicweb/server/repository.py
changeset 11950 68766861debe
parent 11934 ec69125c03a8
child 11962 36851c8b6763
equal deleted inserted replaced
11947:3c58ea2fd745 11950:68766861debe
   152 
   152 
   153 class _CnxSetPool(object):
   153 class _CnxSetPool(object):
   154 
   154 
   155     def __init__(self, source, size):
   155     def __init__(self, source, size):
   156         self._cnxsets = []
   156         self._cnxsets = []
   157         self._queue = queue.Queue()
   157         if size is not None:
   158         for i in range(size):
   158             self._queue = queue.Queue()
   159             cnxset = source.wrapped_connection()
   159             for i in range(size):
   160             self._cnxsets.append(cnxset)
   160                 cnxset = source.wrapped_connection()
   161             self._queue.put_nowait(cnxset)
   161                 self._cnxsets.append(cnxset)
       
   162                 self._queue.put_nowait(cnxset)
       
   163         else:
       
   164             self._queue = None
       
   165             self._source = source
   162         super(_CnxSetPool, self).__init__()
   166         super(_CnxSetPool, self).__init__()
   163 
   167 
   164     def qsize(self):
   168     def qsize(self):
   165         return self._queue.qsize()
   169         q = self._queue
       
   170         if q is None:
       
   171             return None
       
   172         return q.qsize()
   166 
   173 
   167     def get(self):
   174     def get(self):
       
   175         q = self._queue
       
   176         if q is None:
       
   177             return self._source.wrapped_connection()
   168         try:
   178         try:
   169             return self._queue.get(True, timeout=5)
   179             return self._queue.get(True, timeout=5)
   170         except queue.Empty:
   180         except queue.Empty:
   171             raise Exception('no connections set available after 5 secs, probably either a '
   181             raise Exception('no connections set available after 5 secs, probably either a '
   172                             'bug in code (too many uncommited/rolled back '
   182                             'bug in code (too many uncommited/rolled back '
   173                             'connections) or too much load on the server (in '
   183                             'connections) or too much load on the server (in '
   174                             'which case you can try to set a bigger '
   184                             'which case you can try to set a bigger '
   175                             'connections pool size)')
   185                             'connections pool size)')
   176 
   186 
   177     def release(self, cnxset):
   187     def release(self, cnxset):
   178         self._queue.put_nowait(cnxset)
   188         q = self._queue
       
   189         if q is None:
       
   190             cnxset.close(True)
       
   191         else:
       
   192             self._queue.put_nowait(cnxset)
   179 
   193 
   180     def __iter__(self):
   194     def __iter__(self):
   181         for cnxset in self._cnxsets:
   195         for cnxset in self._cnxsets:
   182             yield cnxset
   196             yield cnxset
   183 
   197 
   184     def close(self):
   198     def close(self):
   185         q = self._queue
   199         q = self._queue
   186         while not q.empty():
   200         if q is not None:
   187             cnxset = q.get_nowait()
   201             while not q.empty():
   188             try:
   202                 cnxset = q.get_nowait()
   189                 cnxset.close(True)
   203                 try:
   190             except Exception:
   204                     cnxset.close(True)
   191                 self.exception('error while closing %s' % cnxset)
   205                 except Exception:
       
   206                     self.exception('error while closing %s' % cnxset)
   192 
   207 
   193 
   208 
   194 class Repository(object):
   209 class Repository(object):
   195     """a repository provides access to a set of persistent storages for
   210     """a repository provides access to a set of persistent storages for
   196     entities and relations
   211     entities and relations
   246         """should be called bootstrap_repository, as this is what it does"""
   261         """should be called bootstrap_repository, as this is what it does"""
   247         config = self.config
   262         config = self.config
   248         # copy pool size here since config.init_cube() and config.load_schema()
   263         # copy pool size here since config.init_cube() and config.load_schema()
   249         # reload configuration from file and could reset a manually set pool
   264         # reload configuration from file and could reset a manually set pool
   250         # size.
   265         # size.
   251         pool_size = config['connections-pool-size']
   266         if config['connections-pooler-enabled']:
   252         # 0. init a cnxset of size 1 that will be used to fetch bootstrap information from
   267             pool_size, min_pool_size = config['connections-pool-size'], 1
       
   268         else:
       
   269             pool_size = min_pool_size = None
       
   270         # 0. init a cnxset that will be used to fetch bootstrap information from
   253         #    the database
   271         #    the database
   254         self.cnxsets = _CnxSetPool(self.system_source, 1)
   272         self.cnxsets = _CnxSetPool(self.system_source, min_pool_size)
   255         # 1. set used cubes
   273         # 1. set used cubes
   256         if config.creating or not config.read_instance_schema:
   274         if config.creating or not config.read_instance_schema:
   257             config.bootstrap_cubes()
   275             config.bootstrap_cubes()
   258         else:
   276         else:
   259             self.set_schema(self.config.load_bootstrap_schema(), resetvreg=False)
   277             self.set_schema(self.config.load_bootstrap_schema(), resetvreg=False)
   265             #
   283             #
   266             # restrict appobject_path to only load hooks and entity classes in
   284             # restrict appobject_path to only load hooks and entity classes in
   267             # the registry
   285             # the registry
   268             config.cube_appobject_path = set(('hooks', 'entities'))
   286             config.cube_appobject_path = set(('hooks', 'entities'))
   269             config.cubicweb_appobject_path = set(('hooks', 'entities'))
   287             config.cubicweb_appobject_path = set(('hooks', 'entities'))
   270             # limit connections pool to 1
   288             # limit connections pool size
   271             pool_size = 1
   289             pool_size = min_pool_size
   272         if config.quick_start or config.creating or not config.read_instance_schema:
   290         if config.quick_start or config.creating or not config.read_instance_schema:
   273             # load schema from the file system
   291             # load schema from the file system
   274             if not config.creating:
   292             if not config.creating:
   275                 self.info("set fs instance'schema")
   293                 self.info("set fs instance'schema")
   276             self.set_schema(config.load_schema(expand_cubes=True))
   294             self.set_schema(config.load_schema(expand_cubes=True))