There is a fondamental API that heed must support for the new MeiliSearch engine to be able to support index deletion, the mdb_env_close
.
This function deletes a given environment, after an environment is safely closed it is possible to safely delete it from disk too.
The problem with this function call is that the API user must ensure that no transaction are still alive, but there is no way to ensure that by ourself as the transactions mutexes are handle by LMDB itself, the only way would be to redefine the mutex logic ourselves.
And this why this issue is here, defining the mutex logic in heed and disable the LMDB one (only if a feature is enabled).
I took a look a the best library for synchronization primitives in Rust, parking_lot and the conclusion is that we should use a Mutex for write transactions and a RwLock for read-only transactions.
Thanks to the RwLock we are able to block readers by write-locking it, avoiding readers to acquire read transactions, this will allow heed to ensure that it got exclusive access either for the write and the read part, allowing it to safely delete the environment or any other operation that require exclusively access.
There is one little missing problem: ensuring that the db handle is not used again by the library user. Maybe trying to lock a deleted db should return a specific error, informing the library user that this db handle is invalid.
To enable the user-end locking feature we must first disable the inerrant locking system of LDMB, we can do so by enabling the NO_LOCK
flag when opening an environment.
However, I am not sure about the description of the NO_LOCK
parameter of the mdb_env_open
flag.
For proper operation the caller must enforce single-writer semantics, and must ensure that no readers are using old transactions while a writer is active. The simplest approach is to use an exclusive lock so that no readers may be active at all when a writer begins.
Does it mean that it is not possible to have concurrent readers and writers when the NO_LOCK
flag is set?