]> git.openstreetmap.org Git - nominatim.git/commitdiff
enable connection pools for sqlite
authorSarah Hoffmann <lonvia@denofr.de>
Tue, 5 Dec 2023 11:22:00 +0000 (12:22 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Thu, 7 Dec 2023 08:31:00 +0000 (09:31 +0100)
Connecting is reasonably expensive because the spatialite extension
needs to be loaded. Disable pooling for tests because there is some
memory leak when quickly opening and closing QueuePools with sqlite
connections.

nominatim/api/core.py
test/python/api/conftest.py

index c8045c2d1494167a6a87dc2ef149b783607aa970..b2624227586160c72924e80e25dc887f4150f8aa 100644 (file)
@@ -84,6 +84,14 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
             extra_args: Dict[str, Any] = {'future': True,
                                           'echo': self.config.get_bool('DEBUG_SQL')}
 
+            if self.config.get_int('API_POOL_SIZE') == 0:
+                extra_args['poolclass'] = sa.pool.NullPool
+            else:
+                extra_args['poolclass'] = sa.pool.QueuePool
+                extra_args['max_overflow'] = 0
+                extra_args['pool_size'] = self.config.get_int('API_POOL_SIZE')
+
+
             is_sqlite = self.config.DATABASE_DSN.startswith('sqlite:')
 
             if is_sqlite:
@@ -105,28 +113,12 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
                            host=dsn.get('host'),
                            port=int(dsn['port']) if 'port' in dsn else None,
                            query=query)
-                extra_args['max_overflow'] = 0
-                extra_args['pool_size'] = self.config.get_int('API_POOL_SIZE')
 
             engine = sa_asyncio.create_async_engine(dburl, **extra_args)
 
-            try:
-                async with engine.begin() as conn:
-                    result = await conn.scalar(sa.text('SHOW server_version_num'))
-                    server_version = int(result)
-            except (PGCORE_ERROR, sa.exc.OperationalError):
+            if is_sqlite:
                 server_version = 0
 
-            if server_version >= 110000 and not is_sqlite:
-                @sa.event.listens_for(engine.sync_engine, "connect")
-                def _on_connect(dbapi_con: Any, _: Any) -> None:
-                    cursor = dbapi_con.cursor()
-                    cursor.execute("SET jit_above_cost TO '-1'")
-                    cursor.execute("SET max_parallel_workers_per_gather TO '0'")
-                # Make sure that all connections get the new settings
-                await self.close()
-
-            if is_sqlite:
                 @sa.event.listens_for(engine.sync_engine, "connect")
                 def _on_sqlite_connect(dbapi_con: Any, _: Any) -> None:
                     dbapi_con.run_async(lambda conn: conn.enable_load_extension(True))
@@ -134,6 +126,22 @@ class NominatimAPIAsync: #pylint: disable=too-many-instance-attributes
                     cursor.execute("SELECT load_extension('mod_spatialite')")
                     cursor.execute('SELECT SetDecimalPrecision(7)')
                     dbapi_con.run_async(lambda conn: conn.enable_load_extension(False))
+            else:
+                try:
+                    async with engine.begin() as conn:
+                        result = await conn.scalar(sa.text('SHOW server_version_num'))
+                        server_version = int(result)
+                except (PGCORE_ERROR, sa.exc.OperationalError):
+                    server_version = 0
+
+                if server_version >= 110000:
+                    @sa.event.listens_for(engine.sync_engine, "connect")
+                    def _on_connect(dbapi_con: Any, _: Any) -> None:
+                        cursor = dbapi_con.cursor()
+                        cursor.execute("SET jit_above_cost TO '-1'")
+                        cursor.execute("SET max_parallel_workers_per_gather TO '0'")
+                    # Make sure that all connections get the new settings
+                    await engine.dispose()
 
             self._property_cache['DB:server_version'] = server_version
 
index cb7f324a393fa24e2ddb097e710b92662fc96bd2..8f0604d4076c10b8a06c1f2405d3b12f49873f78 100644 (file)
@@ -198,7 +198,8 @@ def frontend(request, event_loop, tmp_path):
                                                                  db, options))
             return napi.NominatimAPI(Path('/invalid'),
                                      {'NOMINATIM_DATABASE_DSN': f"sqlite:dbname={db}",
-                                      'NOMINATIM_USE_US_TIGER_DATA': 'yes'})
+                                      'NOMINATIM_USE_US_TIGER_DATA': 'yes',
+                                      'NOMINATIM_API_POOL_SIZE': '0'})
     elif request.param == 'postgres_db':
         def mkapi(apiobj, options=None):
             return apiobj.api