Execute a query on a session's connection
(
&self,
session_id: &Uuid,
f: F
)
| 91 | |
| 92 | /// Execute a query on a session's connection |
| 93 | pub fn execute_with_session<F, R>( |
| 94 | &self, |
| 95 | session_id: &Uuid, |
| 96 | f: F |
| 97 | ) -> Result<R, PgSqliteError> |
| 98 | where |
| 99 | F: FnOnce(&Connection) -> Result<R, rusqlite::Error> |
| 100 | { |
| 101 | // First try thread-local cache (fast path) |
| 102 | if let Some(conn_arc) = ThreadLocalConnectionCache::get(session_id) { |
| 103 | let conn = conn_arc.lock(); |
| 104 | return f(&conn).map_err(PgSqliteError::Sqlite); |
| 105 | } |
| 106 | |
| 107 | // Fall back to global map (slow path) |
| 108 | let connections = self.connections.read(); |
| 109 | |
| 110 | // Get the connection Arc |
| 111 | let conn_arc = connections.get(session_id) |
| 112 | .ok_or_else(|| PgSqliteError::Protocol( |
| 113 | format!("No connection found for session {session_id}") |
| 114 | ))?; |
| 115 | |
| 116 | // Clone the Arc to avoid holding the read lock while executing |
| 117 | let conn_arc = conn_arc.clone(); |
| 118 | |
| 119 | // Drop the read lock early |
| 120 | drop(connections); |
| 121 | |
| 122 | // Cache in thread-local storage for next time |
| 123 | ThreadLocalConnectionCache::insert(*session_id, conn_arc.clone()); |
| 124 | |
| 125 | // Now lock the individual connection |
| 126 | let conn = conn_arc.lock(); |
| 127 | f(&conn).map_err(PgSqliteError::Sqlite) |
| 128 | } |
| 129 | |
| 130 | /// Execute a query with a cached connection Arc (avoids HashMap lookup) |
| 131 | pub fn execute_with_cached_connection<F, R>( |