JobStore implementation for Quartz.NET scheduler using RavenDB.
Not exactly a fork of, but inspired by Quartz.NET-RavenDB
Quartz.NET is a full-featured, open source job scheduling system that can be used from smallest apps to large scale enterprise systems.
Quartz.NET on RavenDB is a provider written for Quartz.NET which lets us use the RavenDB NoSQL database as the persistent Job Store for scheduling data (instead of the SQL solutions that are built-in Quartz.NET).
- Can handle high volumes of jobs and triggers.
- Suitable for clustered schedulers.
- Different schedulers (instance names) can share the same database.
First add scheduling to your app using Quartz.NET (example). Then install the NuGet package.
You can either let the package create a IDocumentStore on its own:
using Domla.Quartz.Raven;
using Quartz;
using Quartz.Impl.RavenStore.Example;
using Raven.Client.Documents;
using Raven.Client.Documents.Conventions;
CreateFromProperties().Run();
IHost CreateFromProperties() =>
Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddHostedService<Worker>();
services.AddQuartz(quartz =>
{
// Quartz insists on selecting a serializer.
quartz.SetProperty("quartz.serializer.type", "binary");
// Configure thread pool size for Quartz,
// not directly to RavenJobStore.
quartz.UseDefaultThreadPool(pool => pool.MaxConcurrency = 10);
quartz.UsePersistentStore(store =>
{
// Tell Quartz to use RavenJobStore as store backend,
// creating a DocumentStore along the way.
store.UseRavenDb(configuration =>
{
// To run this demo you need to have running RavenDB at http://localhost:8080.
// Or use a different URL which suits your needs.
configuration.Urls = new[] { "http://localhost:8080" };
// The database is expected to be created.
configuration.Database = "QuartzDemo";
// Time to wait for non-stale query results.
configuration.SecondsToWaitForIndexing = 15; // default
// How often to retry an operation when failed because of a concurrency exception.
configuration.ConcurrencyErrorRetries = 100; // default
// Just for the record - you can prefix the collection
// names for our classes with a common name.
// configuration.CollectionName = "Name";
// Path to a raven client certificate
// configuration.CertPath = "certificate.pem";
// Password for the certificate.
// configuration.CertPass = "secret-password";
});
});
});
services.AddQuartzHostedService(quartz => quartz.WaitForJobsToComplete = true);
})
.Build();
or you can create and configure your own IDocumentStore and let the JobStore use it:
using Domla.Quartz.Raven;
using Quartz;
using Quartz.Impl.RavenStore.Example;
using Raven.Client.Documents;
using Raven.Client.Documents.Conventions;
CreateWithOwnDocumentStore().Run();
IHost CreateWithOwnDocumentStore() =>
Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
// Build and register a Raven document store as usual.
var conventions = new DocumentConventions
{
UseOptimisticConcurrency = true
};
var documentStore = new DocumentStore
{
Conventions = conventions,
// To run this demo you need to have running RavenDB at http://localhost:8080.
// Or use a different URL which suits your needs.
Urls = new[] { "http://localhost:8080" },
// The database is expected to be created.
Database = "QuartzDemo"
};
documentStore.Initialize();
services.AddSingleton<IDocumentStore>(documentStore);
services.AddHostedService<Worker>();
services.AddQuartz(quartz =>
{
// Quartz insists on selecting a serializer.
quartz.SetProperty("quartz.serializer.type", "binary");
// Configure thread pool size for Quartz,
// not directly to RavenJobStore.
quartz.UseDefaultThreadPool(pool => pool.MaxConcurrency = 10);
// Yes, it is that simple.
quartz.UsePersistentStore(store => store.UseRavenDb(services));
});
services.AddQuartzHostedService(quartz => quartz.WaitForJobsToComplete = true);
})
.Build()
.UseRavenJobStoreLogging();