Storage
The store holds tickers, cron occurrences, run history and locks. Without configuration SharpTicker uses an in-memory store, which is lost when the process stops and cannot be shared between instances.
| Store | Package | Shared between instances |
|---|---|---|
| In-memory (default) | SharpTicker |
No |
| Entity Framework Core | SharpTicker.EntityFrameworkCore |
Yes |
| MongoDB | SharpTicker.MongoDB |
Yes |
| Redis | SharpTicker.Caching.StackExchangeRedis |
Yes |
Entity Framework Core
Works with any relational EF Core provider, such as SQL Server, PostgreSQL, SQLite or MySQL. There are two ways to use it.
A separate DbContext
SharpTicker brings its own SharpTickerDbContext:
using Microsoft.EntityFrameworkCore;
using SharpTicker.DependencyInjection;
using SharpTicker.EntityFrameworkCore.DbContextFactory;
using SharpTicker.EntityFrameworkCore.DependencyInjection;
builder.Services.AddSharpTicker(options =>
{
options.AddOperationalStore(ef =>
{
ef.UseSharpTickerDbContext<SharpTickerDbContext>(db =>
db.UseNpgsql(builder.Configuration.GetConnectionString("Scheduler")));
});
});
Your own DbContext
To keep the tables in your application's database and migrations, map them into your own context:
using SharpTicker.EntityFrameworkCore.Customizer;
options.AddOperationalStore(ef =>
{
ef.UseApplicationDbContext<AppDbContext>(ConfigurationType.UseModelCustomizer);
});
With ConfigurationType.UseModelCustomizer the tables are added to your model automatically. With IgnoreModelCustomizer, apply (from SharpTicker.EntityFrameworkCore.Configurations) TimeTickerConfigurations<TimeTickerEntity>, CronTickerConfigurations<CronTickerEntity> and CronTickerOccurrenceConfigurations<CronTickerEntity> yourself in OnModelCreating.
Schema and tables
Tables are created in the ticker schema: TimeTickers, CronTickers and CronTickerOccurrences. Change the schema with ef.SetSchema("..."). Create the tables with EF Core migrations, or with EnsureCreated() / GenerateCreateScript() when you do not use migrations.
Other options: SetDbContextPoolSize(int) (default 1024).
MongoDB
using SharpTicker.MongoDB.DependencyInjection;
options.AddOperationalStore(mongo =>
{
mongo.UseSharpTickerMongoClient("mongodb://localhost:27017", "scheduler");
});
UseExistingMongoClient(databaseName)reuses anIMongoClientthat is already registered in dependency injection.- One of the two is required; startup fails otherwise.
- Collections use the prefix
ticker_(ticker_TimeTickers,ticker_CronTickers,ticker_CronTickerOccurrences). Change it withSetCollectionPrefix("..."). - Indexes are created at startup.
Redis
using SharpTicker.Caching.StackExchangeRedis.DependencyInjection;
options.AddStackExchangeRedis(redis =>
{
redis.Configuration = "localhost:6379";
});
- Set one of
Configuration,ConfigurationOptions,ConnectionMultiplexerorConnectionMultiplexerFactory; startup fails otherwise. InstanceName(defaultsharpticker:) is the prefix under which nodes report that they are alive. Job data uses its owntq:*keys.- Each node sends a heartbeat every
NodeHeartbeatInterval(default one minute). Jobs held by a node that stopped sending heartbeats are released for others. - For trimmed or AOT applications, set
JsonSerializerContext.
Choosing a store
- In-memory for development, tests and single-process tools where losing jobs on restart is acceptable.
- EF Core when you already run a relational database. With your own
DbContextthe tables live next to your data and in your migrations. - MongoDB when your application already uses MongoDB.
- Redis for a fast, shared store when you already run Redis and accept its persistence model.