Hey!
Recently we started using Prodigy for sentences annotation. We use a default ner.manual
recipe for that purpose and have four people working on the same dataset at the same time (web).
A few days ago our other services ran out of database connections, so we started investigating the problem. It turned out that Prodigy grabs hundreds of database connections (a picture is provided below), though we don't see any specific reason for that.
We discovered this issue using 1.10.4 for Linux, but updating to 1.10.5 for Linux gave no results.
We tried limiting connections to 10, but now the service does not even launch. Here's a traceback based on our logs:
Task exception was never retrieved
future: <Task finished name='Task-805' coro=<RequestResponseCycle.run_asgi() done, defined at /usr/local/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py:388> exception=OperationalError('FATAL: too many connections for role "prodigy"\n')>
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py", line 393, in run_asgi
self.logger.error(msg, exc_info=exc)
File "/usr/local/lib/python3.8/logging/__init__.py", line 1463, in error
self._log(ERROR, msg, args, **kwargs)
File "/usr/local/lib/python3.8/logging/__init__.py", line 1577, in _log
self.handle(record)
File "/usr/local/lib/python3.8/logging/__init__.py", line 1586, in handle
if (not self.disabled) and self.filter(record):
File "/usr/local/lib/python3.8/logging/__init__.py", line 807, in filter
result = f.filter(record)
File "cython_src/prodigy/util.pyx", line 121, in prodigy.util.ServerErrorFilter.filter
File "/usr/local/lib/python3.8/site-packages/uvicorn/protocols/http/httptools_impl.py", line 390, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/usr/local/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/fastapi/applications.py", line 140, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/starlette/applications.py", line 134, in __call__
await self.error_middleware(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 178, in __call__
raise exc from None
File "/usr/local/lib/python3.8/site-packages/starlette/middleware/errors.py", line 156, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.8/site-packages/starlette/middleware/base.py", line 25, in __call__
response = await self.dispatch_func(request, self.call_next)
File "/usr/local/lib/python3.8/site-packages/prodigy/app.py", line 198, in reset_db_middleware
response = await call_next(request)
File "/usr/local/lib/python3.8/site-packages/starlette/middleware/base.py", line 45, in call_next
task.result()
File "/usr/local/lib/python3.8/site-packages/starlette/middleware/base.py", line 38, in coro
await self.app(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/starlette/exceptions.py", line 73, in __call__
raise exc from None
File "/usr/local/lib/python3.8/site-packages/starlette/exceptions.py", line 62, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 590, in __call__
await route(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 208, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.8/site-packages/starlette/routing.py", line 41, in app
response = await func(request)
File "/usr/local/lib/python3.8/site-packages/fastapi/routing.py", line 129, in app
raw_response = await run_in_threadpool(dependant.call, **values)
File "/usr/local/lib/python3.8/site-packages/starlette/concurrency.py", line 25, in run_in_threadpool
return await loop.run_in_executor(None, func, *args)
File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.8/site-packages/prodigy/app.py", line 378, in get_session_project
config["total"] = controller.get_total_by_session(session_id)
File "cython_src/prodigy/core.pyx", line 187, in prodigy.core.Controller.get_total_by_session
File "/usr/local/lib/python3.8/site-packages/prodigy/components/db.py", line 207, in __contains__
has_ds = bool(Dataset.get(Dataset.name == name))
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 6430, in get
return sq.get()
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 6860, in get
return clone.execute(database)[0]
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 1898, in inner
return method(self, database, *args, **kwargs)
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 1969, in execute
return self._execute(database)
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 2141, in _execute
cursor = database.execute(self)
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 3142, in execute
return self.execute_sql(sql, params, commit=commit)
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 3136, in execute_sql
self.commit()
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 2902, in __exit__
reraise(new_type, new_type(exc_value, *exc_args), traceback)
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 185, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 3127, in execute_sql
cursor = self.cursor(commit)
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 3111, in cursor
self.connect()
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 3068, in connect
self._initialize_connection(self._state.conn)
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 2902, in __exit__
reraise(new_type, new_type(exc_value, *exc_args), traceback)
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 185, in reraise
raise value.with_traceback(tb)
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 3065, in connect
self._state.set_connection(self._connect())
File "/usr/local/lib/python3.8/site-packages/peewee.py", line 3761, in _connect
conn = psycopg2.connect(database=self.database, **self.connect_params)
File "/usr/local/lib/python3.8/site-packages/psycopg2/__init__.py", line 127, in connect
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
peewee.OperationalError: FATAL: too many connections for role "prodigy"
Is there any chance this could get fixed?
Thanks in advance.