Skip to content

Updated concurrency#6

Merged
CornerstoneCode merged 3 commits intomainfrom
UpdatedConcurrency
Apr 14, 2026
Merged

Updated concurrency#6
CornerstoneCode merged 3 commits intomainfrom
UpdatedConcurrency

Conversation

@CornerstoneCode
Copy link
Copy Markdown
Owner

@CornerstoneCode CornerstoneCode commented Apr 14, 2026

New files
File Purpose
src/SqliteErrorCodes.cs Internal constants and classifiers for SQLITE_BUSY, SQLITE_BUSY_SNAPSHOT (517), SQLITE_BUSY_RECOVERY, SQLITE_LOCKED, etc.
src/Models/SqliteSynchronousMode.cs Enum for PRAGMA synchronous (Off/Normal/Full/Extra) with full durability trade-off documentation
src/Models/WalCheckpointStatus.cs Record returned by GetWalCheckpointStatusAsync — exposes busy flag, total frames, checkpointed frames, and progress %
Modified files
SqliteConcurrencyOptions.cs

Added SynchronousMode (default Normal), UpgradeTransactionsToImmediate (default true), LoggerFactory (excluded from equality)
Added Validate() with bounds checks on all numeric properties
Updated Equals/GetHashCode to include new behavior-affecting properties
SqliteConcurrencyInterceptor.cs

Creates ILogger from options.LoggerFactory
Logs SQLITE_BUSY_SNAPSHOT (Warning), SQLITE_BUSY (Warning), and SQLITE_LOCKED (Error) in CommandFailed/CommandFailedAsync
Logs BEGIN IMMEDIATE upgrades at Debug level
Respects UpgradeTransactionsToImmediate = false; also now catches BEGIN DEFERRED
SqliteConnectionEnhancer.cs

Uses options.SynchronousMode.ToString().ToUpperInvariant() instead of hardcoded NORMAL
Added inline comments on every pragma explaining the reason, trade-off, and safe range
Added GetWalCheckpointStatusAsync() — runs PRAGMA wal_checkpoint(PASSIVE) and returns WalCheckpointStatus
SqliteConcurrencyExtensions.cs

Calls options.Validate() on startup
Retry now catches via SqliteErrorCodes.IsAnyBusy() (covers all extended codes); SQLITE_LOCKED propagates immediately
Backoff replaced with exponential + full jitter: sleep in [baseDelay, 2×baseDelay]
ThreadSafeSqliteContext.cs

Same SqliteErrorCodes-based retry; SQLITE_BUSY_SNAPSHOT restarts the full operation lambda (correct semantics — stale data is re-queried)
Jitter added to backoff
TimeoutException message now identifies whether it was a snapshot error and includes the extended error code
SqliteConcurrencyServiceCollectionExtensions.cs

Resolves ILoggerFactory from the DI container and injects it into options automatically
doc/QUICKSTART.md

Removed all UseWriteQueue references
Replaced the incorrect options table with the real six options, each with accurate defaults and descriptions

What was changed
SqliteConcurrencyServiceCollectionExtensions.cs

Added AddConcurrentSqliteDbContextFactory — registers IDbContextFactory with concurrency settings and auto-injected ILoggerFactory. Factory lifetime defaults to Singleton (appropriate since the factory holds no per-request state).
Updated AddConcurrentSqliteDbContext XML doc to point users toward the factory overload for concurrent workloads.
SqliteConnectionEnhancer.cs

ComputeOptimizedConnectionString now throws ArgumentException when Cache=Shared is detected, with a clear message explaining the WAL incompatibility and pointing to connection pooling as the correct alternative.
Added TryReleaseMigrationLockAsync — checks for a stale __EFMigrationsLock row and optionally deletes it. Accepts a release: false flag for diagnostic-only checks. Includes full XML docs covering when and why stale locks occur.
QUICKSTART.md

"Configure" section now shows both registration paths with guidance on when to use each.
"Real-World Scenario" corrected: the bad pattern now shows the EF thread-safety violation explicitly, and the good pattern uses IDbContextFactory + CreateDbContext() per task.
New "Multi-Instance Deployments and Migration Locks" section with TryReleaseMigrationLockAsync usage and network filesystem warning.
Best Practices list updated to 7 items covering factory pattern, Cache=Shared, migration lock, and single-host constraint.

Summary by CodeRabbit

  • New Features

    • Added fine-grained SQLite concurrency configuration options: SynchronousMode for durability control and UpgradeTransactionsToImmediate for transaction optimization.
    • Introduced factory pattern support via new AddConcurrentSqliteDbContextFactory method for concurrent workload scenarios.
    • Added WAL checkpoint and migration lock management APIs for advanced control.
  • Improvements

    • Enhanced error handling and retry logic with full-jitter exponential backoff and improved error classification.
    • Integrated logging support throughout the concurrency layer.
  • Documentation

    • Updated setup guidance with clearer configuration patterns and concurrent usage best practices.

Here's a summary of every change made:

New files
File	Purpose
src/SqliteErrorCodes.cs	Internal constants and classifiers for SQLITE_BUSY, SQLITE_BUSY_SNAPSHOT (517), SQLITE_BUSY_RECOVERY, SQLITE_LOCKED, etc.
src/Models/SqliteSynchronousMode.cs	Enum for PRAGMA synchronous (Off/Normal/Full/Extra) with full durability trade-off documentation
src/Models/WalCheckpointStatus.cs	Record returned by GetWalCheckpointStatusAsync — exposes busy flag, total frames, checkpointed frames, and progress %
Modified files
SqliteConcurrencyOptions.cs

Added SynchronousMode (default Normal), UpgradeTransactionsToImmediate (default true), LoggerFactory (excluded from equality)
Added Validate() with bounds checks on all numeric properties
Updated Equals/GetHashCode to include new behavior-affecting properties
SqliteConcurrencyInterceptor.cs

Creates ILogger<SqliteConcurrencyInterceptor> from options.LoggerFactory
Logs SQLITE_BUSY_SNAPSHOT (Warning), SQLITE_BUSY (Warning), and SQLITE_LOCKED (Error) in CommandFailed/CommandFailedAsync
Logs BEGIN IMMEDIATE upgrades at Debug level
Respects UpgradeTransactionsToImmediate = false; also now catches BEGIN DEFERRED
SqliteConnectionEnhancer.cs

Uses options.SynchronousMode.ToString().ToUpperInvariant() instead of hardcoded NORMAL
Added inline comments on every pragma explaining the reason, trade-off, and safe range
Added GetWalCheckpointStatusAsync() — runs PRAGMA wal_checkpoint(PASSIVE) and returns WalCheckpointStatus
SqliteConcurrencyExtensions.cs

Calls options.Validate() on startup
Retry now catches via SqliteErrorCodes.IsAnyBusy() (covers all extended codes); SQLITE_LOCKED propagates immediately
Backoff replaced with exponential + full jitter: sleep in [baseDelay, 2×baseDelay]
ThreadSafeSqliteContext.cs

Same SqliteErrorCodes-based retry; SQLITE_BUSY_SNAPSHOT restarts the full operation lambda (correct semantics — stale data is re-queried)
Jitter added to backoff
TimeoutException message now identifies whether it was a snapshot error and includes the extended error code
SqliteConcurrencyServiceCollectionExtensions.cs

Resolves ILoggerFactory from the DI container and injects it into options automatically
doc/QUICKSTART.md

Removed all UseWriteQueue references
Replaced the incorrect options table with the real six options, each with accurate defaults and descriptions
What was changed
SqliteConcurrencyServiceCollectionExtensions.cs

Added AddConcurrentSqliteDbContextFactory<TContext> — registers IDbContextFactory<TContext> with concurrency settings and auto-injected ILoggerFactory. Factory lifetime defaults to Singleton (appropriate since the factory holds no per-request state).
Updated AddConcurrentSqliteDbContext XML doc to point users toward the factory overload for concurrent workloads.
SqliteConnectionEnhancer.cs

ComputeOptimizedConnectionString now throws ArgumentException when Cache=Shared is detected, with a clear message explaining the WAL incompatibility and pointing to connection pooling as the correct alternative.
Added TryReleaseMigrationLockAsync — checks for a stale __EFMigrationsLock row and optionally deletes it. Accepts a release: false flag for diagnostic-only checks. Includes full XML docs covering when and why stale locks occur.
QUICKSTART.md

"Configure" section now shows both registration paths with guidance on when to use each.
"Real-World Scenario" corrected: the bad pattern now shows the EF thread-safety violation explicitly, and the good pattern uses IDbContextFactory + CreateDbContext() per task.
New "Multi-Instance Deployments and Migration Locks" section with TryReleaseMigrationLockAsync usage and network filesystem warning.
Best Practices list updated to 7 items covering factory pattern, Cache=Shared, migration lock, and single-host constraint.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 14, 2026

Warning

Rate limit exceeded

@CornerstoneCode has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 51 minutes and 15 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 51 minutes and 15 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f2ce54c5-09db-466b-89a9-2a30036fc32f

📥 Commits

Reviewing files that changed from the base of the PR and between a662da8 and 94c8790.

📒 Files selected for processing (2)
  • EntityFrameworkCore.Sqlite.Concurrency/EFCore.Sqlite.Concurrency.csproj
  • EntityFrameworkCore.Sqlite.Concurrency/doc/v10_0_3.md
📝 Walkthrough

Walkthrough

This PR introduces new public APIs for WAL checkpoint monitoring and migration lock management, expands concurrency configuration with synchronous mode and transaction-upgrade settings, adds logging support through interceptors, enhances error classification with better SQLite error handling, and updates DI patterns with factory-based context registration.

Changes

Cohort / File(s) Summary
Dependency Updates
EFCore.Sqlite.Concurrency.csproj, packages.lock.json
Updated Microsoft.Extensions.DependencyInjection from 10.0.2 to 10.0.5, Microsoft.SourceLink.GitHub from 8.0.0 to 10.0.201, and added transitive System.IO.Hashing 10.0.5 dependency.
New Models & Types
src/Models/SqliteSynchronousMode.cs, src/Models/WalCheckpointStatus.cs, src/SqliteErrorCodes.cs
Added SqliteSynchronousMode enum with four PRAGMA settings (Off, Normal, Full, Extra), WalCheckpointStatus record with checkpoint progress computation, and internal SqliteErrorCodes class for SQLite error code classification and helper methods.
Configuration & Options
src/Models/SqliteConcurrencyOptions.cs
Added SynchronousMode, UpgradeTransactionsToImmediate, and LoggerFactory properties; introduced Validate() method with range checks; updated equality/hash semantics to include new options.
Service Registration
src/ExtensionMethods/SqliteConcurrencyServiceCollectionExtensions.cs
Enhanced AddConcurrentSqliteDbContext<TContext> to inject ILoggerFactory from DI; added new AddConcurrentSqliteDbContextFactory<TContext> method for factory-based context registration.
Connection Management & APIs
src/SqliteConnectionEnhancer.cs
Added validation rejecting shared cache, expanded PRAGMA configuration in ApplyRuntimePragmas (mmap_size, temp_store, cache_size, locking_mode, secure_delete, wal_autocheckpoint), and introduced public async methods GetWalCheckpointStatusAsync() and TryReleaseMigrationLockAsync() for WAL monitoring and migration lock management.
Core Extensions & Retry Logic
src/SqliteConcurrencyExtensions.cs
Added options.Validate() enforcement; expanded busy error detection via SqliteErrorCodes.IsAnyBusy(ex) instead of hardcoded error code; replaced deterministic exponential backoff with full-jitter exponential backoff strategy.
Interceptor & Logging
src/SqliteConcurrencyInterceptor.cs
Added optional ILogger<SqliteConcurrencyInterceptor> with command failure instrumentation via CommandFailed/CommandFailedAsync overrides; refined UpgradeToBeginImmediate logic to detect BEGIN variants and avoid double-upgrades; introduced command text truncation for logging.
Thread-Safe Context
src/ThreadSafeSqliteContext.cs
Updated write retry to use SqliteErrorCodes.IsAnyBusy(ex) and IsBusySnapshot(ex) for better error classification; replaced simple exponential delay with full-jitter backoff; enhanced timeout exception messages with extended error code details.
Documentation
doc/QUICKSTART.md, doc/v10_0_0.md
Updated QUICKSTART with new AddConcurrentSqliteDbContext<T> and factory patterns, added concurrent-workload guidance with IDbContextFactory<T> emphasis, documented multi-instance migration locking, updated configuration options table, and revised claim from "100% write reliability" to "Eliminates write contention errors".

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

  • V10.0.2 optimizations #3: Modifies the same core components (SqliteConcurrencyServiceCollectionExtensions, SqliteConcurrencyOptions, SqliteConnectionEnhancer, SqliteConcurrencyInterceptor) with overlapping DI registration, concurrency options, and retry/backoff logic enhancements.
  • V10 optimizations - automated NuGet deployment failure  #5: Updates dependencies and lockfile artifacts (EFCore.Sqlite.Concurrency.csproj, packages.lock.json) for the same project.

Poem

🐰 With PRAGMA refinements and checkpoint care,
New factory patterns float through the air,
Jitter and logging, error codes bright,
SQLite contention? No more—goodnight!
WAL migration locks now set free!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Updated concurrency' is vague and generic, using non-descriptive phrasing that does not convey meaningful information about the specific changes in this substantial pull request. Replace with a more specific title that highlights the main change, such as 'Add logging, SQLite error classification, and factory pattern support for concurrent workloads' or 'Enhance concurrency handling with error codes, SynchronousMode, and IDbContextFactory.'
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 85.29% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch UpdatedConcurrency

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@CornerstoneCode CornerstoneCode merged commit 4062398 into main Apr 14, 2026
2 checks passed
@CornerstoneCode CornerstoneCode deleted the UpdatedConcurrency branch April 14, 2026 04:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant