Repository navigation
Conversation
|
Thanks! TBH I am not sure about the
While I think that Also, why are these problems not solved by a longer busy timeout? |
|
I don't fully grasp why either, but it's evident that there's some kind of deadlock going on (sometimes I have to kill the session with my example above). Some more info:
IMO, reads should be allowed, and thus all writers should be carefully guarded with |
|
FWIW, I added this patch to a Shiny app that manages cron jobs with ~20 workers reading from a liteq queue, and there have been no more issues. |
|
I think I solved the issue of |
|
I found this interesting read. As it turns out, |
|
Right. But you are saying that this is not the case for |
|
What is not the case for |
|
Right, sorry, misunderstood. |
|
Quick question. I suppose that this is low priority among your (many) other projects, but is there any roadmap or estimate for this? Just to adjust my expectations. Also, please, let me know if there's something more I could do to help. Thanks in advance. |
|
I'll take a look some time this week, sorry for the delay. |
|
Do you have some tips to make the code in #28 fail more often? I cannot make it reliably fail, so far I have seen one failure out of a hundred runs. Should I just run it longer? Increase the number of subprocesses? Decrease the sleep time in the while loop? Decrease the busy timeout? |
|
Setting a one second timeout and increasing the number of subprocesses to 20 did it seemingly... |
|
FYI I did compile RSQLite with |
|
OTOH, unfortunately this PR does not fix the issue when RSQLite is compiled without |
Yes, there's a certain combination that I suppose depends on the number of cores, the scheduler...
+1, but
Are you sure? Did you reload the namespace properly before trying? Because I don't have any issues with the patch regardless of the number of workers and the sleep between |
Yeah, totally sure. I added your code as a test case, and increased the number of subprocesses. |
Ideally yes, but that will not be easy. We would need to implement our own randomized exponential backoff.
Sure. We can still merge this, but it will not solve all concurrency issues. At least now I know what is going on. :) I think... |
Isn't this running the wrong (Sorry to insist, but note that |
There is only one, just installed it above this.
Yeah, that is weird. It seems that the |
Sorry, I got confused with the branch name in your prompt.
|
|
Or maybe the other way around: just send the pragma once in |
Maybe. It is set multiple times because sqlite3 seems to reset it. But anyway, this does not solve the concurrency issues, there might be multiple concurrent writers as well, so this needs to be solved either in RSQLite or with implementing our own backoff. |
|
I'll merge this soon (probably today) after some changes. |
Codecov Report
@@ Coverage Diff @@
## master #29 +/- ##
======================================
Coverage 0.00% 0.00%
======================================
Files 5 5
Lines 318 321 +3
======================================
- Misses 318 321 +3
Continue to review full report at Codecov.
|
This is not a real DB, and we could even just use filelock for this, actually.
|
Great, thanks. Let me know if I can help. |
More explicit layers, better names.
|
This gave me a good excuse to understand the DB functions (again) and refactor it, so they are easier to maintain. I'll merge when the checks come back clean. |
|
FYI I wrote up the concurrency issues at https://blog.r-hub.io/2021/03/13/rsqlite-parallel/ |
| # Order is important here! | ||
| dbExecute(con, "CREATE TABLE foo (id INT)") | ||
| dbExecute(con, "BEGIN IMMEDIATE") |
There was a problem hiding this comment.
I've tested current changes and it works great for my use case, even without the recent changes in RSQLite.
However, I'd like to ask why is this particular order important here. AFAIK, SQLite locks the whole database, not individual tables, and CREATE TABLE is a write operation. With this ordering, my test in #28 shows FAILED messages that are afterwards recovered. If I invert these two instructions, I don't see any failed messages anymore.
There was a problem hiding this comment.
Because SQLite will not lock a DB that has no tables, apparently, even with BEGIN IMMEDIATE. I am not entirely sure, but this is my best guess.
Did you see the FAILED messages with or without the recent changes in RSQLite? In your test FAILED means that (R)SQLite has given up and liteq needs to requeue?
There was a problem hiding this comment.
Because SQLite will not lock a DB that has no tables, apparently, even with
BEGIN IMMEDIATE. I am not entirely sure, but this is my best guess.
But this doesn't apply here. Whenever liteq is trying to set a new message, there's a queue set up, and thus there's at least one table. So, for messages, I believe, BEGIN IMMEDIATE should be before CREATE TABLE.
Did you see the
FAILEDmessages with or without the recent changes in RSQLite? In your testFAILEDmeans that (R)SQLite has given up and liteq needs to requeue?
Without.
There was a problem hiding this comment.
But this doesn't apply here.
It actually does. This is a different DB. That's why it is mostly managed differently from the db.R functions. This is an (almost) empty db, that we use as a lock file. (I wrote liteq before the filelock package.)
Without
Can you please try with the latest RSQLite that has the changes? It is on CRAN now.
There was a problem hiding this comment.
Actually, it was with the latest RSQLite, I wasn't aware of the update: half of the messages fail with current ordering, no fails with BEGIN IMMEDIATE in the first place.
There was a problem hiding this comment.
Actually, I have test failures and incorrect behavior with both versions. :(
|
Any interest is 'waking' this old thread up @Enchufa2 @gaborcsardi ? Context: So I got |
|
It is better to create a new PR for this. |

This is my take at #28, which partially revisits #26. This PR basically
do_db_executetake the lock, because every call to it is a write;publishtake the lock, same reason;EXCLUSIVElocks withIMMEDIATElocks.This works very well for my use case in #28, but please take a look to ensure that I'm not missing something. Compared to master, tests are much quicker now, but two tests fail, which I believe are spurious errors due to the fact that IMMEDIATE locks can coexist with readers: