fix(auth): make advisory locks dialect-aware and harden SQLite DSN - #10509
Merged
Conversation
Fixes #10506. Two failures hit deployments that use the default SQLite auth database: 1. advisorylock executed PostgreSQL-only SQL (pg_advisory_lock / pg_try_advisory_lock) unconditionally. On a SQLite auth DB the job store, agent store and node registry migrations failed with "no such function: pg_advisory_lock". WithLockCtx/TryWithLockCtx now branch on the gorm dialect: PostgreSQL keeps the cross-process advisory lock, every other dialect uses a context-aware, per-key in-process lock (a SQLite auth DB is effectively single-process, so serializing within the process is sufficient). 2. The SQLite auth DSN set no busy timeout, so transient SQLITE_BUSY over network-backed storage (SMB/CIFS/NFS, e.g. Azure Files) failed the auth migration immediately with "database is locked". The DSN now sets _busy_timeout=5000 and _txlock=immediate (caller-supplied values are preserved). WAL is intentionally not enabled since its shared-memory mmap does not work over network filesystems. Docs note that PostgreSQL should be used when the data directory lives on shared storage. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:claude-opus-4-8 [Claude Code]
Exercises the exact caller chain that failed in the issue: auth.InitDB(sqlite) -> jobs.NewJobStore -> advisorylock.WithLockCtx -> AutoMigrate. Before the dialect-aware advisory lock fix this failed with "no such function: pg_advisory_lock"; the test now asserts it migrates cleanly on a SQLite auth DB. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:claude-opus-4-8 [Claude Code]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #10506.
Two failures hit deployments that use the default SQLite auth database (
LOCALAI_AUTH=truewithoutLOCALAI_AUTH_DATABASE_URL=postgres://...):1.
no such function: pg_advisory_lockon SQLitecore/services/advisorylockexecuted PostgreSQL-only SQL (pg_advisory_lock/pg_try_advisory_lock/pg_advisory_unlock) unconditionally. The auth DB can be SQLite, so the job store, agent store and node registry migrations failed withmigrating job tables: advisorylock: acquiring lock 105: no such function: pg_advisory_lock(non-fatal in standalone startup, fatal in distributed mode).WithLockCtx/TryWithLockCtxnow branch on the gorm dialect:2.
database is lockedover network storageThe SQLite auth DSN set no busy timeout, so transient
SQLITE_BUSYover network-backed storage (SMB/CIFS/NFS, e.g. Azure Files / Azure Container Apps) failedAutoMigrateimmediately withfailed to migrate auth tables: database is locked(the reporter's Azure case).buildSQLiteDSNnow sets_busy_timeout=5000and_txlock=immediate(caller-supplied values preserved). WAL is intentionally not enabled - its shared-memory mmap does not work over network filesystems, which is the failing environment. Docs note that PostgreSQL should be used when the data directory lives on shared storage.Tests
advisorylock: executes under lock, serializes concurrent goroutines on the same key, returns error on already-cancelled context, andTryWithLockCtxreturns(false, nil)when the key is held.buildSQLiteDSNunit tests: plain path,:memory:, pre-existing query string, and no-override of caller-supplied pragmas.InitDBSQLite test still pass.Verification
gofmtclean;go vetclean (with and without-tags auth); full advisorylock suite incl. Postgres testcontainers green; auth DSN + InitDB tests green;golangci-lint --new-from-merge-base=origin/masterreports 0 issues.Assisted-by: Claude:claude-opus-4-8 [Claude Code]