🚀 Building the Best SQL-Backed Job Queue with WJb and UkrGuru.Sql in .NET
Managing background jobs is a common challenge in modern applications. Simple in-memory queues work for quick tasks, but what happens when your app restarts or crashes? Data loss. That’s why persistence matters.
Today, I’m excited to share SqlQueueWJb, the most powerful and practical demo in the WJb.Samples repository. This isn’t just another sample—it’s the best demo yet, because it combines:
✅ WJb – a flexible workflow/job engine
✅ UkrGuru.Sql – lightweight SQL integration for .NET
✅ SQL-backed persistence – reliability and auditability for enterprise-grade apps
🌟 Why SqlQueueWJb Is the Best Demo
Unlike basic queues, SqlQueueWJb solves real-world problems:
- Persistent Queue: Jobs survive app restarts.
- Full Lifecycle Logging: Every step is tracked—Compacted → Queued → Expanded → Running → Completed/Failed.
- Job History: Completed jobs are archived for auditing.
- Background Service: Runs seamlessly with
IHostedService. - Minimal Boilerplate: Thanks to UkrGuru.Sql, database operations are clean and simple.
This is not theory—it’s production-ready design. If you’ve ever needed a reliable job processor, this is the demo you’ve been waiting for.
🔑 Key Features
- Custom
SqlJobProcessorimplementingIJobProcessor+BackgroundService - SQL persistence using UkrGuru.Sql
- Priority-based queueing and status transitions
- Easy integration with WJb actions via
IActionFactory
⚙️ Setup Instructions
1. Install NuGet Packages
dotnet add package WJb
dotnet add package UkrGuru.Sql
2. Initialize the Database
Before running the app, execute Resources/InitDb.sql in SQL Server Management Studio or via sqlcmd:
IF NOT EXISTS (SELECT 1 FROM sys.databases WHERE name = 'SqlQueueWJb')
BEGIN
CREATE DATABASE [SqlQueueWJb];
END
GO
USE [SqlQueueWJb];
GO
-- Creates WJbQueue and WJbHistory tables
This script ensures the database exists and sets up the required tables for queue and history.
3. Configure Services
Add these lines in Program.cs:
services.AddSql(conn);
services.AddSingleton<IActionFactory, DemoActionFactory>();
services.AddSingleton<IJobProcessor, SqlJobProcessor>();
services.AddHostedService(sp => (SqlJobProcessor)sp.GetRequiredService<IJobProcessor>());
4. Enqueue a Job
var job = await proc.CompactAsync("SayHello", new { name = "Viktor" });
await proc.EnqueueJobAsync(job);
âś… Sample Output
info: SqlQueueWJb.SqlJobProcessor[0] JobProcessor started
info: SqlQueueWJb.SqlJobProcessor[0] Job Compacted
info: SqlQueueWJb.SqlJobProcessor[0] Job Queued
info: SqlQueueWJb.SqlJobProcessor[0] Job Expanded
info: SqlQueueWJb.SqlJobProcessor[0] Job Running
SayHello Viktor!
info: SqlQueueWJb.SqlJobProcessor[0] Job Completed
info: SqlQueueWJb.SqlJobProcessor[0] JobProcessor stopped
🔥 Why This Demo Stands Out
This isn’t just another sample—it’s the best demo in WJb.Samples because it demonstrates:
- Enterprise-grade reliability: No lost jobs, even after crashes.
- Auditability: Every job is logged and archived.
- Scalability: Ready for high-volume processing.
- Simplicity: Minimal code, maximum power.
If you’ve struggled with job queues before, SqlQueueWJb is the solution you’ve been looking for.
📌 Next Steps
- Explore the full source: GitHub – WJb.Samples
- Add custom actions and chain jobs for complex workflows.
- Extend with retry policies or distributed processing.
Top comments (0)