diff --git a/go.mod b/go.mod index f66ad14ff..f368c7871 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/superseriousbusiness/gotosocial go 1.21 +replace modernc.org/sqlite => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.29.5-concurrency-workaround + toolchain go1.21.3 require ( diff --git a/go.sum b/go.sum index 9273583e9..7885ace6e 100644 --- a/go.sum +++ b/go.sum @@ -721,6 +721,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA= github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +gitlab.com/NyaaaWhatsUpDoc/sqlite v1.29.5-concurrency-workaround h1:cyYnGCVJ0zLW2Q0pCepy++ERHegWcKpl5JD1MiTKUuw= +gitlab.com/NyaaaWhatsUpDoc/sqlite v1.29.5-concurrency-workaround/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= @@ -1121,8 +1123,6 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= -modernc.org/sqlite v1.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE= -modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/vendor/modernc.org/sqlite/AUTHORS b/vendor/modernc.org/sqlite/AUTHORS index 580af028f..8ded64c33 100644 --- a/vendor/modernc.org/sqlite/AUTHORS +++ b/vendor/modernc.org/sqlite/AUTHORS @@ -22,6 +22,7 @@ Josh Klein Logan Snow Michael Hoffmann Michael Rykov +Morgan Bazalgette Ross Light Saed SayedAhmed Steffen Butzer diff --git a/vendor/modernc.org/sqlite/CONTRIBUTORS b/vendor/modernc.org/sqlite/CONTRIBUTORS index 01c92d911..efa080a0c 100644 --- a/vendor/modernc.org/sqlite/CONTRIBUTORS +++ b/vendor/modernc.org/sqlite/CONTRIBUTORS @@ -27,6 +27,7 @@ Mark Summerfield Matthew Gabeler-Lee Michael Hoffmann Michael Rykov +Morgan Bazalgette Romain Le Disez Ross Light Saed SayedAhmed diff --git a/vendor/modernc.org/sqlite/Makefile b/vendor/modernc.org/sqlite/Makefile index 357baa017..fffd890fc 100644 --- a/vendor/modernc.org/sqlite/Makefile +++ b/vendor/modernc.org/sqlite/Makefile @@ -55,7 +55,7 @@ clean: edit: @touch log - @if [ -f "Session.vim" ]; then novim -S & else novim -p Makefile all_test.go generator.go & fi + @if [ -f "Session.vim" ]; then novim -S & else novim -p Makefile go.mod builder.json all_test.go generator.go & fi editor: gofmt -l -s -w . 2>&1 | tee log-editor diff --git a/vendor/modernc.org/sqlite/README.md b/vendor/modernc.org/sqlite/README.md index aa45ff87a..f47ad3240 100644 --- a/vendor/modernc.org/sqlite/README.md +++ b/vendor/modernc.org/sqlite/README.md @@ -16,7 +16,7 @@ allowing one of the maintainers to work on it also in office hours. ## Documentation -[godoc.org/modernc.org/sqlite](http://godoc.org/modernc.org/sqlite) +[pkg.go.dev/modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite) ## Builders @@ -74,3 +74,8 @@ RAM. Shown are the best of 3 runs. TOTAL....................................................... 5.525s TOTAL....................................................... 4.637s This particular test executes 16.1% faster in the C version. + +## Troubleshooting + +* Q: **How can I write to a database concurrently without getting the `database is locked` error (or `SQLITE_BUSY`)?** + * A: You can't. The C sqlite implementation does not allow concurrent writes, and this libary does not modify that behaviour. You can, however, use [DB.SetMaxOpenConns(1)](https://pkg.go.dev/database/sql#DB.SetMaxOpenConns) so that only 1 connection is ever used by the `DB`, allowing concurrent access to DB without making the writes concurrent. More information on issues [#65](https://gitlab.com/cznic/sqlite/-/issues/65) and [#106](https://gitlab.com/cznic/sqlite/-/issues/106). diff --git a/vendor/modernc.org/sqlite/builder.json b/vendor/modernc.org/sqlite/builder.json index 4b42126d9..2955e178c 100644 --- a/vendor/modernc.org/sqlite/builder.json +++ b/vendor/modernc.org/sqlite/builder.json @@ -1,6 +1,6 @@ { "autogen": "", "autotag": "darwin/(amd64|arm64)|freebsd/(amd64|arm64)|linux/(386|amd64|arm|arm64|ppc64le|riscv64|s390x)|windows/(amd64|arm64)", - "autoupdate": "darwin/(amd64|arm64)|freebsd/(amd64|arm64)|linux/(386|amd64|arm|arm64|ppc64le|riscv64|s390x)|windows/(amd64|arm64)", - "test": "darwin/(amd64|arm64)|freebsd/(amd64|arm64)|linux/(386|amd64|arm|arm64|ppc64le|riscv64|s390x)|windows/(amd64|arm64)" + "autoupdate": "", + "test": "darwin/(amd64|arm64)|freebsd/(amd64|arm64)|linux/(386|amd64|arm|arm64|loon64|ppc64le|riscv64|s390x)|windows/(amd64|arm64)" } diff --git a/vendor/modernc.org/sqlite/sqlite.go b/vendor/modernc.org/sqlite/sqlite.go index 5ead81923..4f0546d24 100644 --- a/vendor/modernc.org/sqlite/sqlite.go +++ b/vendor/modernc.org/sqlite/sqlite.go @@ -21,7 +21,6 @@ import ( "strconv" "strings" "sync" - "sync/atomic" "time" "unsafe" @@ -491,17 +490,6 @@ func toNamedValues(vals []driver.Value) (r []driver.NamedValue) { func (s *stmt) exec(ctx context.Context, args []driver.NamedValue) (r driver.Result, err error) { var pstmt uintptr - var done int32 - if ctx != nil { - if ctxDone := ctx.Done(); ctxDone != nil { - select { - case <-ctxDone: - return nil, ctx.Err() - default: - } - defer interruptOnDone(ctx, s.c, &done)() - } - } defer func() { if pstmt != 0 { @@ -514,13 +502,13 @@ func (s *stmt) exec(ctx context.Context, args []driver.NamedValue) (r driver.Res err = e } } - - if ctx != nil && atomic.LoadInt32(&done) != 0 { - r, err = nil, ctx.Err() - } }() - for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0 && atomic.LoadInt32(&done) == 0; { + for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0; { + if err := ctx.Err(); err != nil { + return nil, err + } + if pstmt, err = s.c.prepareV2(&psql); err != nil { return nil, err } @@ -528,6 +516,7 @@ func (s *stmt) exec(ctx context.Context, args []driver.NamedValue) (r driver.Res if pstmt == 0 { continue } + err = func() (err error) { n, err := s.c.bindParameterCount(pstmt) if err != nil { @@ -604,17 +593,6 @@ func (s *stmt) Query(args []driver.Value) (driver.Rows, error) { //TODO StmtQuer func (s *stmt) query(ctx context.Context, args []driver.NamedValue) (r driver.Rows, err error) { var pstmt uintptr - var done int32 - if ctx != nil { - if ctxDone := ctx.Done(); ctxDone != nil { - select { - case <-ctxDone: - return nil, ctx.Err() - default: - } - defer interruptOnDone(ctx, s.c, &done)() - } - } var allocs []uintptr @@ -630,14 +608,16 @@ func (s *stmt) query(ctx context.Context, args []driver.NamedValue) (r driver.Ro } } - if ctx != nil && atomic.LoadInt32(&done) != 0 { - r, err = nil, ctx.Err() - } else if r == nil && err == nil { + if r == nil && err == nil { r, err = newRows(s.c, pstmt, allocs, true) } }() - for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0 && atomic.LoadInt32(&done) == 0; { + for psql := s.psql; *(*byte)(unsafe.Pointer(psql)) != 0; { + if err := ctx.Err(); err != nil { + return nil, err + } + if pstmt, err = s.c.prepareV2(&psql); err != nil { return nil, err } @@ -755,10 +735,6 @@ func (t *tx) exec(ctx context.Context, sql string) (err error) { defer t.c.free(psql) //TODO use t.conn.ExecContext() instead - if ctx != nil && ctx.Done() != nil { - defer interruptOnDone(ctx, t.c, nil)() - } - if rc := sqlite3.Xsqlite3_exec(t.c.tls, t.c.db, psql, 0, 0, 0); rc != sqlite3.SQLITE_OK { return t.c.errstr(rc) } @@ -766,51 +742,10 @@ func (t *tx) exec(ctx context.Context, sql string) (err error) { return nil } -// interruptOnDone sets up a goroutine to interrupt the provided db when the -// context is canceled, and returns a function the caller must defer so it -// doesn't interrupt after the caller finishes. -func interruptOnDone( - ctx context.Context, - c *conn, - done *int32, -) func() { - if done == nil { - var d int32 - done = &d - } - - donech := make(chan struct{}) - - go func() { - select { - case <-ctx.Done(): - // don't call interrupt if we were already done: it indicates that this - // call to exec is no longer running and we would be interrupting - // nothing, or even possibly an unrelated later call to exec. - if atomic.AddInt32(done, 1) == 1 { - c.interrupt(c.db) - } - case <-donech: - } - }() - - // the caller is expected to defer this function - return func() { - // set the done flag so that a context cancellation right after the caller - // returns doesn't trigger a call to interrupt for some other statement. - atomic.AddInt32(done, 1) - close(donech) - } -} - type conn struct { db uintptr // *sqlite3.Xsqlite3 tls *libc.TLS - // Context handling can cause conn.Close and conn.interrupt to be invoked - // concurrently. - sync.Mutex - writeTimeFormat string beginMode string } @@ -1333,13 +1268,7 @@ func (c *conn) prepareV2(zSQL *uintptr) (pstmt uintptr, err error) { // // void sqlite3_interrupt(sqlite3*); func (c *conn) interrupt(pdb uintptr) (err error) { - c.Lock() // Defend against race with .Close invoked by context handling. - - defer c.Unlock() - - if c.tls != nil { - sqlite3.Xsqlite3_interrupt(c.tls, pdb) - } + sqlite3.Xsqlite3_interrupt(c.tls, pdb) return nil } @@ -1460,15 +1389,11 @@ func (c *conn) Close() (err error) { dmesg("conn %p: err %v", c, err) }() } - c.Lock() // Defend against race with .interrupt invoked by context handling. - - defer c.Unlock() if c.db != 0 { if err := c.closeV2(c.db); err != nil { return err } - c.db = 0 } @@ -1476,6 +1401,7 @@ func (c *conn) Close() (err error) { c.tls.Close() c.tls = nil } + return nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index f269e87a1..eb45321f4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1286,7 +1286,7 @@ modernc.org/mathutil # modernc.org/memory v1.7.2 ## explicit; go 1.18 modernc.org/memory -# modernc.org/sqlite v1.29.5 +# modernc.org/sqlite v1.29.5 => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.29.5-concurrency-workaround ## explicit; go 1.20 modernc.org/sqlite modernc.org/sqlite/lib @@ -1299,3 +1299,4 @@ modernc.org/token # mvdan.cc/xurls/v2 v2.5.0 ## explicit; go 1.19 mvdan.cc/xurls/v2 +# modernc.org/sqlite => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.29.5-concurrency-workaround