Paste: Messing around wrt. #3158
| Author: | Z |
| Mode: | factor |
| Date: | Wed, 17 Jun 2026 21:58:51 |
Plain Text |
USING: accessors calendar continuations db db.sqlite
db.sqlite.lib kernel math namespaces threads ;
IN: test
: db-path ( -- path ) "/tmp/locked-repro.db" ;
: init-db ( -- )
db-path <sqlite-db> [
"CREATE TABLE IF NOT EXISTS t (id INTEGER PRIMARY KEY, val TEXT)" sql-command
] with-db ;
: hold-write-lock ( -- )
db-path <sqlite-db> [
[
"INSERT INTO t (val) VALUES ('locker')" sql-command
2 seconds sleep
] with-transaction
] with-db ;
: sqlite-busy? ( error -- ? )
dup sqlite-error? [ n>> 5 = ] [ drop f ] if ;
: try-write-retry ( retries-left -- )
dup 0 <= [ drop "gave up: still locked" throw ] [
[
drop "INSERT INTO t (val) VALUES ('victim')" sql-command
] [
dup sqlite-busy? [
drop 200 milliseconds sleep 1 - try-write-retry
] [
nip rethrow
] if
] recover
] if ;
: try-write-ok ( -- )
db-path <sqlite-db> [ 20 try-write-retry ] with-db ;
: repro-fail ( -- )
init-db
[ hold-write-lock ] "locker" spawn drop
500 milliseconds sleep
db-path <sqlite-db> [ "INSERT INTO t (val) VALUES ('victim')" sql-command ] with-db ;
: repro-ok ( -- )
init-db
[ hold-write-lock ] "locker" spawn drop
500 milliseconds sleep
try-write-ok ;
SYMBOL: db-conn-a
SYMBOL: db-conn-b
: open-db-a ( -- ) "repro.db" sqlite-open db-conn-a set ;
: open-db-b ( -- ) "repro.db" sqlite-open db-conn-b set ;
: close-db-a ( -- ) db-conn-a get sqlite-close ;
: close-db-b ( -- ) db-conn-b get sqlite-close ;
: exec-sql-a ( str -- ) db-conn-a get swap sqlite-prepare dup sqlite-next drop sqlite-finalize ;
: exec-sql-b ( str -- ) db-conn-b get swap sqlite-prepare dup sqlite-next drop sqlite-finalize ;
: repro-lock ( -- )
init-db
open-db-a
open-db-b
[
"BEGIN IMMEDIATE" exec-sql-a
1 seconds sleep
"COMMIT" exec-sql-a
close-db-a
] "w1" spawn drop
[
300 milliseconds sleep
"BEGIN IMMEDIATE" exec-sql-b
"COMMIT" exec-sql-b
close-db-b
] "w2" spawn drop
2 seconds sleep ;
New Annotation