SA Bugzilla – Bug 5167
Bayes plugin attempts write to read-only tied database
Last modified: 2019-09-25 03:15:03 UTC
I'm writing a new test BayesStore backend and I've implemented separate tie_db_readonly() and tie_db_writable() methods which connect to the right places. I've found a problem in that the BayesStore::touch_tok_all method is being called when I only have a read-only connection to the database. touch_tok_all is being called from Bayes::scan() in order to update the access times on the tokens, but it needs to tie a writable database connection first. I'm not sure how to properly go about fixing this as the tie/untie logic in Bayes.pm looks quite complex! Thanks.
(In reply to comment #0) > I've found a problem in that the BayesStore::touch_tok_all method is being > called when I only have a read-only connection to the database. Yep, that's normal. > touch_tok_all is being called from Bayes::scan() in order to update the access > times on the tokens, but it needs to tie a writable database connection first. That depends on the implementation. The DBM backend, for instance, defers the writes to a journal, which gets synced periodically. So the DB stays r/o, and the journal gets updated from the cleanup() call. So you could, for instance, call tie_db_writable() in cleanup and sync out the atime updates, or you could ignore atime updates if you don't want to do expiry, or ...
or emulate the DBM backend and create an append-only, many-writers-1-reader journal
I understand what you're saying, but doesn't this mean that Bayes is making assumptions about the storage backend beyond the interface specification ? It's effectively doing: - give me a read-only instance of the storage; - do an update (assumption: it's ok because I know the backend will defer this until later when I call sync in a read/write context...) This isn't a safe assumption (although it is true for DBM backends) unless the interface specification is changed so that touch_tok_all becomes semantically schedule_touch_tok_all - for example the SQL backend doesn't use any kind of journal but it gets round this by not (really) differentiating between ro and rw connections. I could implement a journal but at the moment I'm thinking about making tie_db_*() a no-op and handling connections internally. That might actually be a neater approach for what I want anyway. I worry that I might be missing something in the greater OO architecture of SA though since I'm fairly new to it.
Dev kibbitzing, not a bug. Likely no longer relevant in any case.