61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
"""A pool for sqlite connections."""
|
|
import threading
|
|
|
|
from sqlalchemy.pool import NullPool, SingletonThreadPool
|
|
|
|
from homeassistant.helpers.frame import report
|
|
|
|
from .const import DB_WORKER_PREFIX
|
|
|
|
POOL_SIZE = 5
|
|
|
|
|
|
class RecorderPool(SingletonThreadPool, NullPool):
|
|
"""A hybrid of NullPool and SingletonThreadPool.
|
|
|
|
When called from the creating thread or db executor acts like SingletonThreadPool
|
|
When called from any other thread, acts like NullPool
|
|
"""
|
|
|
|
def __init__(self, *args, **kw): # pylint: disable=super-init-not-called
|
|
"""Create the pool."""
|
|
kw["pool_size"] = POOL_SIZE
|
|
SingletonThreadPool.__init__(self, *args, **kw)
|
|
|
|
@property
|
|
def recorder_or_dbworker(self) -> bool:
|
|
"""Check if the thread is a recorder or dbworker thread."""
|
|
thread_name = threading.current_thread().name
|
|
return bool(
|
|
thread_name == "Recorder" or thread_name.startswith(DB_WORKER_PREFIX)
|
|
)
|
|
|
|
def _do_return_conn(self, conn):
|
|
if self.recorder_or_dbworker:
|
|
return super()._do_return_conn(conn)
|
|
conn.close()
|
|
|
|
def shutdown(self):
|
|
"""Close the connection."""
|
|
if self.recorder_or_dbworker and self._conn and (conn := self._conn.current()):
|
|
conn.close()
|
|
|
|
def dispose(self):
|
|
"""Dispose of the connection."""
|
|
if self.recorder_or_dbworker:
|
|
return super().dispose()
|
|
|
|
def _do_get(self):
|
|
if self.recorder_or_dbworker:
|
|
return super()._do_get()
|
|
report(
|
|
"accesses the database without the database executor; "
|
|
"Use homeassistant.components.recorder.get_instance(hass).async_add_executor_job() "
|
|
"for faster database operations",
|
|
exclude_integrations={"recorder"},
|
|
error_if_core=False,
|
|
)
|
|
return super( # pylint: disable=bad-super-call
|
|
NullPool, self
|
|
)._create_connection()
|