eQuantic.TickerQ.EntityFrameworkCore.CosmosDb 1.0.10

dotnet add package eQuantic.TickerQ.EntityFrameworkCore.CosmosDb --version 1.0.10
                    
NuGet\Install-Package eQuantic.TickerQ.EntityFrameworkCore.CosmosDb -Version 1.0.10
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="eQuantic.TickerQ.EntityFrameworkCore.CosmosDb" Version="1.0.10" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="eQuantic.TickerQ.EntityFrameworkCore.CosmosDb" Version="1.0.10" />
                    
Directory.Packages.props
<PackageReference Include="eQuantic.TickerQ.EntityFrameworkCore.CosmosDb" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add eQuantic.TickerQ.EntityFrameworkCore.CosmosDb --version 1.0.10
                    
#r "nuget: eQuantic.TickerQ.EntityFrameworkCore.CosmosDb, 1.0.10"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package eQuantic.TickerQ.EntityFrameworkCore.CosmosDb@1.0.10
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=eQuantic.TickerQ.EntityFrameworkCore.CosmosDb&version=1.0.10
                    
Install as a Cake Addin
#tool nuget:?package=eQuantic.TickerQ.EntityFrameworkCore.CosmosDb&version=1.0.10
                    
Install as a Cake Tool

eQuantic.TickerQ.EntityFrameworkCore.CosmosDb

NuGet NuGet Publish .NET 8+ License: MIT

Note: This is a community-maintained provider for TickerQ. This package is maintained by eQuantic and is not an official TickerQ package.

Azure Cosmos DB provider for TickerQ - A lightweight, developer-friendly library for queuing and executing cron and time-based jobs in the background.

Overview

This provider enables TickerQ to use Azure Cosmos DB as the persistence layer for storing and managing scheduled jobs.

✨ Features

  • 🚀 Multi-framework Support: .NET 8.0 and .NET 9.0
  • 🌐 Azure Cosmos DB: Globally distributed, multi-model database service
  • 📦 EF Core Cosmos Provider: Uses official Microsoft.EntityFrameworkCore.Cosmos
  • 🔒 Optimistic Concurrency: ETags for distributed locking
  • 🎯 Full TickerQ Compatibility: Works seamlessly with TickerQ 2.5.3+
  • High Performance: Low-latency reads and writes with automatic indexing
  • 🌍 Global Distribution: Multi-region replication for high availability
  • 📈 Elastic Scaling: Automatically scales throughput and storage

📋 Requirements

.NET Version EF Core Cosmos Version eQuantic.TickerQ Version
.NET 8.0 8.0.21 2.5.3+
.NET 9.0 9.0.10 2.5.3+

Important: This package depends on eQuantic.TickerQ.* packages (not the original TickerQ.*). These are eQuantic-maintained forks with InternalsVisibleTo configured to allow this provider to access internal APIs.

Installation

dotnet add package eQuantic.TickerQ.EntityFrameworkCore.CosmosDb

From Source

Since this provider requires access to internal members of TickerQ (via InternalsVisibleTo), if building from source you need the forked version:

# Clone the repository
git clone https://github.com/equantic/TickerQ.git
cd TickerQ

# Build the CosmosDb provider
dotnet build src/eQuantic.TickerQ.EntityFrameworkCore.CosmosDb/eQuantic.TickerQ.EntityFrameworkCore.CosmosDb.csproj --configuration Release

Usage

Add the Cosmos DB provider to your application:

using eQuantic.TickerQ.EntityFrameworkCore.CosmosDb.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Add TickerQ with Cosmos DB persistence
builder.Services.AddTickerQ(options =>
{
    options.AddCosmosDbOperationalStore(cosmosOptions =>
    {
        // Option 1: Using connection string
        cosmosOptions.ConnectionString = "AccountEndpoint=https://...;AccountKey=...";
        cosmosOptions.DatabaseName = "TickerQ";

        // Option 2: Using endpoint and key separately
        cosmosOptions.AccountEndpoint = "https://your-account.documents.azure.com:443/";
        cosmosOptions.AccountKey = "your-account-key";
        cosmosOptions.DatabaseName = "TickerQ";

        // Optional: Configure region
        cosmosOptions.Region = "East US";

        // Optional: Performance tuning
        cosmosOptions.MaxRetryAttempts = 3;
        cosmosOptions.MaxRetryWaitTime = TimeSpan.FromSeconds(30);
        cosmosOptions.EnableContentResponseOnWrite = false;
    });
});

var app = builder.Build();
app.Run();

Advanced Configuration

The Cosmos DB provider supports the same advanced configuration options as the EF Core provider:

Seed Initial Tickers
builder.Services.AddTickerQ(options =>
{
    options.AddCosmosDbOperationalStore(
        cosmosOptions =>
        {
            cosmosOptions.ConnectionString = "AccountEndpoint=https://...;AccountKey=...";
            cosmosOptions.DatabaseName = "TickerQ";
        },
        optionsBuilder =>
        {
            // Seed initial tickers (time-based and cron-based)
            optionsBuilder.UseTickerSeeder(
                async timeTicker =>
                {
                    await timeTicker.AddAsync(new TimeTicker
                    {
                        Id = Guid.NewGuid(),
                        Function = "CleanupLogs",
                        ExecutionTime = DateTime.UtcNow.AddSeconds(5),
                    });
                },
                async cronTicker =>
                {
                    await cronTicker.AddAsync(new CronTicker
                    {
                        Id = Guid.NewGuid(),
                        Expression = "0 0 * * *", // every day at 00:00 UTC
                        Function = "CleanupLogs"
                    });
                });
        });
});
Cancel Missed Tickers on Startup
builder.Services.AddTickerQ(options =>
{
    options.AddCosmosDbOperationalStore(
        cosmosOptions =>
        {
            cosmosOptions.ConnectionString = "AccountEndpoint=https://...;AccountKey=...";
            cosmosOptions.DatabaseName = "TickerQ";
        },
        optionsBuilder =>
        {
            // Cancel any missed tickers tied to this node on application start
            optionsBuilder.CancelMissedTickersOnAppStart();
        });
});
Ignore Memory Cron Tickers
builder.Services.AddTickerQ(options =>
{
    options.AddCosmosDbOperationalStore(
        cosmosOptions =>
        {
            cosmosOptions.ConnectionString = "AccountEndpoint=https://...;AccountKey=...";
            cosmosOptions.DatabaseName = "TickerQ";
        },
        optionsBuilder =>
        {
            // Don't automatically seed memory-based cron tickers
            optionsBuilder.IgnoreSeedMemoryCronTickers();
        });
});
Using Custom DbContext

You can provide your own DbContext to customize Cosmos DB configuration:

public class MyCustomCosmosContext : CosmosDbTickerContext
{
    public MyCustomCosmosContext(DbContextOptions options, CosmosDbOptions cosmosOptions)
        : base(options, cosmosOptions)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Add your custom Cosmos DB configurations here
        modelBuilder.Entity<TimeTickerEntity>()
            .HasPartitionKey(e => e.Id);
    }
}

// In Program.cs
builder.Services.AddTickerQ(options =>
{
    options.AddCosmosDbOperationalStore<MyCustomCosmosContext>(cosmosOptions =>
    {
        cosmosOptions.ConnectionString = "AccountEndpoint=https://...;AccountKey=...";
        cosmosOptions.DatabaseName = "TickerQ";
    });
});

Configuration Options

Property Description Default
ConnectionString Complete Cosmos DB connection string -
AccountEndpoint Cosmos DB account endpoint URL -
AccountKey Cosmos DB account key -
DatabaseName Database name to use for TickerQ data "TickerQ"
Region Preferred Azure region null
MaxRetryAttempts Maximum number of retry attempts for failed requests 3
MaxRetryWaitTime Maximum time to wait between retries 30 seconds
EnableContentResponseOnWrite Return full document content on write operations false

Technical Details

Package Dependencies

This package depends on eQuantic-maintained forks of TickerQ libraries published under the eQuantic.* namespace:

Package Purpose
eQuantic.TickerQ Core TickerQ library with InternalsVisibleTo
eQuantic.TickerQ.Utilities TickerQ utilities with InternalsVisibleTo
eQuantic.TickerQ.EntityFrameworkCore EF Core provider base with InternalsVisibleTo

These packages are functionally identical to the original TickerQ.* packages but include InternalsVisibleTo attributes that allow this Cosmos DB provider to access internal APIs required for implementation.

Why Forked Packages Are Needed

The original TickerQ library uses internal members (ExternalProviderConfigServiceAction, ExternalProviderConfigApplicationAction, and BasePersistenceProvider) to allow external providers to configure services and implement persistence. These internal members are necessary for implementing persistence providers but are not publicly accessible.

Our fork (https://github.com/equantic/TickerQ) adds InternalsVisibleTo attributes to expose these APIs:

<InternalsVisibleTo Include="eQuantic.TickerQ.EntityFrameworkCore.CosmosDb" />

This allows the CosmosDb provider to access the required internal APIs without exposing them publicly in the main library. The forked packages are published as eQuantic.TickerQ.* to avoid conflicts with the original packages.

Cosmos DB Collections

The provider creates the following containers in your Cosmos DB database:

  • TimeTickers: Stores one-time scheduled jobs
  • CronTickers: Stores recurring cron-based jobs
  • CronTickerOccurrences: Stores individual occurrences of cron jobs

All containers use the document id as the partition key for optimal distribution.

When to Use Cosmos DB vs SQL Server

✅ Use Cosmos DB when you need:

  • Global distribution and multi-region deployments
  • Low-latency access from anywhere in the world
  • Automatic horizontal scaling
  • 99.999% availability SLA
  • Flexible schema and JSON document storage
  • Serverless or consumption-based pricing

✅ Use SQL Server when you need:

  • Complex relational queries with JOINs and GROUP BY
  • ACID transactions across multiple tables
  • Lower cost for smaller workloads
  • On-premises or existing SQL infrastructure
  • Strong consistency guarantees

Differences from Relational Provider

Cosmos DB is a NoSQL database with different characteristics than SQL databases:

  • No foreign keys: Navigation properties are not mapped
  • No table inheritance: Each entity type gets its own container
  • JSON storage: Complex types are stored as JSON within documents
  • Partition keys: Each container uses id as the partition key
  • No joins: Data must be denormalized for optimal queries
  • No transactions across documents: Unlike SQL, Cosmos DB doesn't support traditional ACID transactions across multiple documents
  • Optimistic concurrency: Uses ETags (via LockHolder property) for concurrency control instead of pessimistic locking

Cosmos DB Query Limitations

Be aware of these Cosmos DB limitations when using this provider:

  • No GROUP BY: Cosmos DB doesn't support GroupBy operations
  • No complex joins: Cross-container queries are not supported
  • No distributed transactions: Each document operation is atomic, but multi-document transactions are limited
  • ⚠️ Limited DISTINCT: Only works on primitive types
  • ⚠️ Query complexity: Very complex queries may need to be executed client-side
  • Fully supported: WHERE, ORDER BY, TOP/TAKE, SELECT, COUNT, SUM, MIN, MAX, AVG

The current implementation avoids these limitations and works seamlessly with Cosmos DB's capabilities.

Project Structure

eQuantic.TickerQ.EntityFrameworkCore.CosmosDb/
├── Configurations/
│   ├── CronTickerCosmosConfiguration.cs
│   ├── CronTickerOccurrenceCosmosConfiguration.cs
│   └── TimeTickerCosmosConfiguration.cs
├── DependencyInjection/
│   └── ServiceExtension.cs
├── Infrastructure/
│   ├── CosmosDbOptions.cs
│   └── CosmosDbTickerContext.cs
└── README.md

Framework Support

This package uses multi-targeting to support both .NET 8.0 and .NET 9.0 in a single NuGet package:

  • net8.0: Uses Microsoft.EntityFrameworkCore.Cosmos 8.0.21
  • net9.0: Uses Microsoft.EntityFrameworkCore.Cosmos 9.0.10

When you install this package, NuGet automatically selects the correct version based on your project's target framework.

Compatibility with Upstream

This package depends on a fork that maintains full compatibility with the upstream TickerQ repository. The only changes to the original code are:

  1. Adding <InternalsVisibleTo Include="eQuantic.TickerQ.EntityFrameworkCore.CosmosDb" /> to 3 project files
  2. This CosmosDb provider project (not included in upstream solution)

We actively sync with upstream:

git remote add upstream https://github.com/arcenox/TickerQ.git
git fetch upstream
git merge upstream/main

Contributing

Issues and pull requests are welcome at https://github.com/equantic/TickerQ

If you have suggestions for the TickerQ core library, please contribute directly to the upstream project: https://github.com/arcenox/TickerQ

Versioning

This package follows Semantic Versioning:

  • Major version: Breaking changes to public API
  • Minor version: New features, backward compatible
  • Patch version: Bug fixes, backward compatible

Version History

  • 1.0.7: Fixed GetCronTickerRequestViaOccurrence to use 2-query approach instead of navigation property, maintains CronTickerEntity as independent container
  • 1.0.6: Added feature parity with EF Core provider (UseTickerSeeder, CancelMissedTickersOnAppStart, custom DbContext support)
  • 1.0.5: Updated dependencies to eQuantic.TickerQ.* v2.5.3.1 (correct dependency chain)
  • 1.0.4: Updated dependencies to use eQuantic.TickerQ.* packages (fixes InternalsVisibleTo access issues)
  • 1.0.3: Initial transition to eQuantic.TickerQ.* dependencies
  • 1.0.2: Added .NET 9.0 support with EF Core Cosmos 9.0.10
  • 1.0.1: Fixed NuGet package dependency versions (changed from TickerQ.* 1.0.0 to 2.5.3)
  • 1.0.0: Initial release with .NET 8.0 support (⚠️ had InternalsVisibleTo access issues)

License

This provider follows the same MIT license as the main TickerQ library.

Support

For issues specific to the Cosmos DB provider:

For general TickerQ questions:

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.10 167 10/19/2025
1.0.9 159 10/19/2025
1.0.8 156 10/19/2025
1.0.7 159 10/19/2025
1.0.6 169 10/19/2025
1.0.5 162 10/19/2025
1.0.4 166 10/19/2025
1.0.3 112 10/18/2025
1.0.2 112 10/18/2025
1.0.1 101 10/18/2025
1.0.0 99 10/18/2025