Threads and processes
Threads
Section titled “Threads”A Database object is safe to share between threads, with no lock of your
own:
- every method releases the GIL, so other Python threads keep running;
- searches run in parallel;
- writes (
add,upsert,delete,persist,compact) wait for each other and for running searches instead of failing.
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor(8) as pool: results = list(pool.map(lambda q: db.search(q, 10), queries))For many queries at once, search_batch(queries, k) parallelises inside Rust.
Processes
Section titled “Processes”A database directory can be open in one place at a time. A second open,
from this process or another, raises BlockingIOError:
a = srvdb.Database("./db", dimension=384)b = srvdb.Database("./db", dimension=384) # BlockingIOError: already openShare one Database object instead of opening the same path twice. The lock is
released when the object is garbage-collected or the process exits, even after
a crash. For multiple processes, put one process in charge of the database and
send it requests.
SrvDB is Send + Sync. Searches take &self; writes take &mut self.
Wrap it in Arc<RwLock<SrvDB>> to mix readers and a writer across threads.
Design: ADR 0005.