How offset and when should ReaderCheck be called?
Opened this issue · 5 comments
Should I call ReaderCheck everytime before
func (env *Env) Update(fn TxnOp) error
and
func (env *Env) View(fn TxnOp) error
No, managed transactions know how to clean up after themselves. If you are worried about crashed processes you can just call ReaderCheck
once, after you have opened the DB. That way stale reader slots from a crashed process will be cleaned.
@LMDB I don't think that's completely correct. If a single (daemon) process accesses the database then yes, calling ReaderCheck
once when the process starts should be sufficient. As long as the process does not leak view transactions (by misusing the API for unmanaged Txns) then the process would be wasting cycles calling ReaderCheck
again later in the same lifecycle.
@zwb-ict If multiple processes access the database environment concurrently then I think it's wise for all processing which create update Txns to call ReaderCheck
periodically. But I would not suggest calling it for every write. The frequency with which the method must be called is application specific.
edit: reader processes should also check for stale readers at startup, later during runtime as well if unmanaged view transactions are used.
A method I have used in the past to call ReaderCheck
is to call it repeatedly from its own goroutine in a loop triggered by a time.Tick
channel. You may choose a duration for the channel timer that works for your application.
edit: YMMV with the above technique. There are other ways to implement periodic checks.
Good luck.
@bmatsuo Can env be used between multi goroutine and why?
It seems that txn cann't
A thread can only use one transaction at a time, plus any child transactions. Each transaction belongs to one thread.
@zwb-ict Yes, an Env type can be used from multiple goroutines. And in general, as you point out, Txn objects cannot be shared between goroutines (it doesn't matter if you synchronize their usage or not.
However, a View Txn (Readonly) may be used in multiple goroutines as long as the uses are synchronized in some way. This is because lmdb-go made the decision to open every Env with the C flag MDB_NOTLS. This is documented in the godoc for Env.Open.
This detail is discussed immediately following the passage you have quoted.
A thread can only use one transaction at a time, plus any child transactions. Each transaction belongs to one thread. See below. The #MDB_NOTLS flag changes this for read-only transactions.
You can see more information about MDB_NOTLS in the documentation for mdb_env_open. I hope this helps.