SQLite: Fix thread pool exhaustion
This commit is contained in:
@@ -16,8 +16,9 @@ impl SqliteStore {
|
|||||||
key: &[u8],
|
key: &[u8],
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
) -> trc::Result<Option<Vec<u8>>> {
|
) -> trc::Result<Option<Vec<u8>>> {
|
||||||
let conn = self.conn_pool.get().map_err(into_error)?;
|
let manager = self.conn_pool.clone();
|
||||||
self.spawn_worker(move || {
|
self.spawn_worker(move || {
|
||||||
|
let conn = manager.get().map_err(into_error)?;
|
||||||
let mut result = conn
|
let mut result = conn
|
||||||
.prepare_cached("SELECT v FROM t WHERE k = ?")
|
.prepare_cached("SELECT v FROM t WHERE k = ?")
|
||||||
.map_err(into_error)?;
|
.map_err(into_error)?;
|
||||||
@@ -42,8 +43,9 @@ impl SqliteStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn put_blob(&self, key: &[u8], data: &[u8]) -> trc::Result<()> {
|
pub(crate) async fn put_blob(&self, key: &[u8], data: &[u8]) -> trc::Result<()> {
|
||||||
let conn = self.conn_pool.get().map_err(into_error)?;
|
let manager = self.conn_pool.clone();
|
||||||
self.spawn_worker(move || {
|
self.spawn_worker(move || {
|
||||||
|
let conn = manager.get().map_err(into_error)?;
|
||||||
conn.prepare_cached("INSERT OR REPLACE INTO t (k, v) VALUES (?, ?)")
|
conn.prepare_cached("INSERT OR REPLACE INTO t (k, v) VALUES (?, ?)")
|
||||||
.map_err(into_error)?
|
.map_err(into_error)?
|
||||||
.execute([key, data])
|
.execute([key, data])
|
||||||
@@ -54,8 +56,9 @@ impl SqliteStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn delete_blob(&self, key: &[u8]) -> trc::Result<bool> {
|
pub(crate) async fn delete_blob(&self, key: &[u8]) -> trc::Result<bool> {
|
||||||
let conn = self.conn_pool.get().map_err(into_error)?;
|
let manager = self.conn_pool.clone();
|
||||||
self.spawn_worker(move || {
|
self.spawn_worker(move || {
|
||||||
|
let conn = manager.get().map_err(into_error)?;
|
||||||
conn.prepare_cached("DELETE FROM t WHERE k = ?")
|
conn.prepare_cached("DELETE FROM t WHERE k = ?")
|
||||||
.map_err(into_error)?
|
.map_err(into_error)?
|
||||||
.execute([key])
|
.execute([key])
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ impl SqliteStore {
|
|||||||
query: &str,
|
query: &str,
|
||||||
params_: &[Value<'_>],
|
params_: &[Value<'_>],
|
||||||
) -> trc::Result<T> {
|
) -> trc::Result<T> {
|
||||||
let conn = self.conn_pool.get().map_err(into_error)?;
|
let manager = self.conn_pool.clone();
|
||||||
self.spawn_worker(move || {
|
self.spawn_worker(move || {
|
||||||
|
let conn = manager.get().map_err(into_error)?;
|
||||||
let mut s = conn.prepare_cached(query).map_err(into_error)?;
|
let mut s = conn.prepare_cached(query).map_err(into_error)?;
|
||||||
let params = params_
|
let params = params_
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ impl SqliteStore {
|
|||||||
SUBSPACE_TELEMETRY_SPAN,
|
SUBSPACE_TELEMETRY_SPAN,
|
||||||
SUBSPACE_TELEMETRY_METRIC,
|
SUBSPACE_TELEMETRY_METRIC,
|
||||||
SUBSPACE_SEARCH_INDEX,
|
SUBSPACE_SEARCH_INDEX,
|
||||||
|
SUBSPACE_DIRECTORY,
|
||||||
] {
|
] {
|
||||||
let table = char::from(table);
|
let table = char::from(table);
|
||||||
conn.execute(
|
conn.execute(
|
||||||
@@ -93,16 +94,22 @@ impl SqliteStore {
|
|||||||
.map_err(into_error)?;
|
.map_err(into_error)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let table = char::from(SUBSPACE_INDEXES);
|
for table in [
|
||||||
conn.execute(
|
SUBSPACE_INDEXES,
|
||||||
&format!(
|
SUBSPACE_REGISTRY_IDX,
|
||||||
"CREATE TABLE IF NOT EXISTS {table} (
|
SUBSPACE_REGISTRY_IDX_GLOBAL,
|
||||||
|
] {
|
||||||
|
let table = char::from(table);
|
||||||
|
conn.execute(
|
||||||
|
&format!(
|
||||||
|
"CREATE TABLE IF NOT EXISTS {table} (
|
||||||
k BLOB PRIMARY KEY
|
k BLOB PRIMARY KEY
|
||||||
)"
|
)"
|
||||||
),
|
),
|
||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
.map_err(into_error)?;
|
.map_err(into_error)?;
|
||||||
|
}
|
||||||
|
|
||||||
for table in [SUBSPACE_COUNTER, SUBSPACE_QUOTA, SUBSPACE_IN_MEMORY_COUNTER] {
|
for table in [SUBSPACE_COUNTER, SUBSPACE_QUOTA, SUBSPACE_IN_MEMORY_COUNTER] {
|
||||||
conn.execute(
|
conn.execute(
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ impl SqliteStore {
|
|||||||
where
|
where
|
||||||
U: Deserialize + 'static,
|
U: Deserialize + 'static,
|
||||||
{
|
{
|
||||||
let conn = self.conn_pool.get().map_err(into_error)?;
|
let manager = self.conn_pool.clone();
|
||||||
self.spawn_worker(move || {
|
self.spawn_worker(move || {
|
||||||
|
let conn = manager.get().map_err(into_error)?;
|
||||||
let mut result = conn
|
let mut result = conn
|
||||||
.prepare_cached(&format!(
|
.prepare_cached(&format!(
|
||||||
"SELECT v FROM {} WHERE k = ?",
|
"SELECT v FROM {} WHERE k = ?",
|
||||||
@@ -24,7 +25,7 @@ impl SqliteStore {
|
|||||||
let key = key.serialize(0);
|
let key = key.serialize(0);
|
||||||
result
|
result
|
||||||
.query_row([&key], |row| {
|
.query_row([&key], |row| {
|
||||||
U::deserialize(row.get_ref(0)?.as_bytes()?)
|
U::deserialize_with_key(&key, row.get_ref(0)?.as_bytes()?)
|
||||||
.map_err(|err| rusqlite::Error::ToSqlConversionFailure(err.into()))
|
.map_err(|err| rusqlite::Error::ToSqlConversionFailure(err.into()))
|
||||||
})
|
})
|
||||||
.optional()
|
.optional()
|
||||||
@@ -38,9 +39,9 @@ impl SqliteStore {
|
|||||||
params: IterateParams<T>,
|
params: IterateParams<T>,
|
||||||
mut cb: impl for<'x> FnMut(&'x [u8], &'x [u8]) -> trc::Result<bool> + Sync + Send,
|
mut cb: impl for<'x> FnMut(&'x [u8], &'x [u8]) -> trc::Result<bool> + Sync + Send,
|
||||||
) -> trc::Result<()> {
|
) -> trc::Result<()> {
|
||||||
let conn = self.conn_pool.get().map_err(into_error)?;
|
let manager = self.conn_pool.clone();
|
||||||
|
|
||||||
self.spawn_worker(move || {
|
self.spawn_worker(move || {
|
||||||
|
let conn = manager.get().map_err(into_error)?;
|
||||||
let table = char::from(params.begin.subspace());
|
let table = char::from(params.begin.subspace());
|
||||||
let begin = params.begin.serialize(0);
|
let begin = params.begin.serialize(0);
|
||||||
let end = params.end.serialize(0);
|
let end = params.end.serialize(0);
|
||||||
@@ -113,8 +114,9 @@ impl SqliteStore {
|
|||||||
let key = key.into();
|
let key = key.into();
|
||||||
let table = char::from(key.subspace());
|
let table = char::from(key.subspace());
|
||||||
let key = key.serialize(0);
|
let key = key.serialize(0);
|
||||||
let conn = self.conn_pool.get().map_err(into_error)?;
|
let manager = self.conn_pool.clone();
|
||||||
self.spawn_worker(move || {
|
self.spawn_worker(move || {
|
||||||
|
let conn = manager.get().map_err(into_error)?;
|
||||||
match conn
|
match conn
|
||||||
.prepare_cached(&format!("SELECT v FROM {table} WHERE k = ?"))
|
.prepare_cached(&format!("SELECT v FROM {table} WHERE k = ?"))
|
||||||
.map_err(into_error)?
|
.map_err(into_error)?
|
||||||
|
|||||||
@@ -14,12 +14,10 @@ use trc::AddContext;
|
|||||||
|
|
||||||
impl SqliteStore {
|
impl SqliteStore {
|
||||||
pub(crate) async fn write(&self, batch: Batch<'_>) -> trc::Result<AssignedIds> {
|
pub(crate) async fn write(&self, batch: Batch<'_>) -> trc::Result<AssignedIds> {
|
||||||
let mut conn = self
|
let manager = self.conn_pool.clone();
|
||||||
.conn_pool
|
|
||||||
.get()
|
|
||||||
.map_err(into_error)
|
|
||||||
.caused_by(trc::location!())?;
|
|
||||||
self.spawn_worker(move || {
|
self.spawn_worker(move || {
|
||||||
|
let mut conn = manager.get().map_err(into_error)?;
|
||||||
|
|
||||||
let mut account_id = u32::MAX;
|
let mut account_id = u32::MAX;
|
||||||
let mut collection = u8::MAX;
|
let mut collection = u8::MAX;
|
||||||
let mut document_id = u32::MAX;
|
let mut document_id = u32::MAX;
|
||||||
@@ -271,12 +269,9 @@ impl SqliteStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn purge_store(&self) -> trc::Result<()> {
|
pub(crate) async fn purge_store(&self) -> trc::Result<()> {
|
||||||
let conn = self
|
let manager = self.conn_pool.clone();
|
||||||
.conn_pool
|
|
||||||
.get()
|
|
||||||
.map_err(into_error)
|
|
||||||
.caused_by(trc::location!())?;
|
|
||||||
self.spawn_worker(move || {
|
self.spawn_worker(move || {
|
||||||
|
let conn = manager.get().map_err(into_error)?;
|
||||||
for subspace in [SUBSPACE_QUOTA, SUBSPACE_COUNTER, SUBSPACE_IN_MEMORY_COUNTER] {
|
for subspace in [SUBSPACE_QUOTA, SUBSPACE_COUNTER, SUBSPACE_IN_MEMORY_COUNTER] {
|
||||||
conn.prepare_cached(&format!("DELETE FROM {} WHERE v = 0", char::from(subspace),))
|
conn.prepare_cached(&format!("DELETE FROM {} WHERE v = 0", char::from(subspace),))
|
||||||
.map_err(into_error)
|
.map_err(into_error)
|
||||||
@@ -292,12 +287,10 @@ impl SqliteStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn delete_range(&self, from: impl Key, to: impl Key) -> trc::Result<()> {
|
pub(crate) async fn delete_range(&self, from: impl Key, to: impl Key) -> trc::Result<()> {
|
||||||
let conn = self
|
let manager = self.conn_pool.clone();
|
||||||
.conn_pool
|
|
||||||
.get()
|
|
||||||
.map_err(into_error)
|
|
||||||
.caused_by(trc::location!())?;
|
|
||||||
self.spawn_worker(move || {
|
self.spawn_worker(move || {
|
||||||
|
let conn = manager.get().map_err(into_error)?;
|
||||||
|
|
||||||
conn.prepare_cached(&format!(
|
conn.prepare_cached(&format!(
|
||||||
"DELETE FROM {} WHERE k >= ? AND k < ?",
|
"DELETE FROM {} WHERE k >= ? AND k < ?",
|
||||||
char::from(from.subspace()),
|
char::from(from.subspace()),
|
||||||
|
|||||||
Reference in New Issue
Block a user