Job Fundamentals
This guide covers the fundamental concepts of TickerQ jobs at a high level. For focused guides on specific topics, see:
Job Function Basics
Function Signature
All TickerQ job functions must follow this pattern:
[TickerFunction("FunctionName")]
public async Task FunctionName(
TickerFunctionContext context,
CancellationToken cancellationToken)
{
// Job logic here
}Function Context
The TickerFunctionContext provides access to job metadata:
public class TickerFunctionContext
{
public Guid Id { get; } // Job ID
public TickerType Type { get; } // TimeTicker or CronTicker
public int RetryCount { get; } // Current retry attempt
public DateTime ScheduledFor { get; } // Intended fire time (UTC)
public bool IsDue { get; } // Whether job is due
public string FunctionName { get; } // Function name
public CronOccurrenceOperations CronOccurrenceOperations { get; } // Cron-specific operations
public void RequestCancellation() // Request cancellation for the current job
}ScheduledFor represents the time the job was meant to fire (UTC), not when it actually started executing. This is especially useful for:
- Cron jobs: it reflects the cron boundary (for example,
12:00,12:05,12:10). - Time tickers: it reflects the scheduled execution time, even if the job starts late.
Prefer ScheduledFor when anchoring data queries or business logic to a schedule, and use DateTime.UtcNow only when you truly need the current wall-clock time.
Typed Request Context
For easier request handling, use the typed version:
[TickerFunction("ProcessOrder")]
public async Task ProcessOrder(
TickerFunctionContext<OrderRequest> context,
CancellationToken cancellationToken)
{
var order = context.Request; // Directly typed request
await ProcessOrderAsync(order, cancellationToken);
}Job Priorities (Overview)
TickerQ jobs can be tagged with a priority via TickerTaskPriority. Currently, the scheduler treats LongRunning specially (runs on a separate long-running path), while High, Normal, and Low are primarily metadata for observability and future scheduling strategies.
See Job Priorities for details and examples.
Job Chaining (Overview)
TimeTicker supports parent–child job relationships for multi-step workflows. See Job Chaining for the full guide on run conditions, fluent builders, and nested chains.
Job Status Lifecycle
Understanding job status helps with monitoring and debugging:
Idle → Queued → InProgress → Done/Failed/Cancelled/SkippedStatus Definitions
| Status | Description |
|---|---|
Idle | Job created but not yet queued |
Queued | Job is in queue waiting to execute |
InProgress | Job is currently executing |
Done | Job completed (executed after due time) |
DueDone | Job completed (executed at due time) |
Failed | Job failed after all retries |
Cancelled | Job was cancelled |
Skipped | Job was skipped (e.g., duplicate prevented) |
Job Cancellation
Jobs can be cancelled from within the function:
[TickerFunction("LongRunningTask")]
public async Task LongRunningTask(
TickerFunctionContext context,
CancellationToken cancellationToken)
{
// Check cancellation token
if (cancellationToken.IsCancellationRequested)
return;
// Or cancel programmatically
if (shouldCancel)
context.RequestCancellation();
}Batch Operations
TimeTickers can be grouped as batches with a parent:
var batchParent = new TimeTickerEntity
{
Function = "ProcessBatch",
ExecutionTime = DateTime.UtcNow,
// ... properties
};
var batchChild1 = new TimeTickerEntity
{
Function = "ProcessItem1",
ParentId = batchParent.Id,
BatchParent = batchParent.Id,
RunCondition = RunCondition.OnSuccess
};
var batchChild2 = new TimeTickerEntity
{
Function = "ProcessItem2",
ParentId = batchParent.Id,
BatchParent = batchParent.Id,
RunCondition = RunCondition.OnSuccess
};Request Data Handling
Creating Request Data
// Simple type
var request = TickerHelper.CreateTickerRequest(new EmailRequest
{
To = "user@example.com",
Subject = "Welcome",
Body = "Thanks for joining!"
});
// Complex type
var request = TickerHelper.CreateTickerRequest(new OrderProcessingRequest
{
OrderId = 12345,
Items = new[] { /* ... */ },
CustomerId = 67890
});Reading Request Data
// In job function
var request = await TickerRequestProvider.GetRequestAsync<EmailRequest>(
context,
cancellationToken
);
// Or use typed context
[TickerFunction("ProcessOrder")]
public async Task ProcessOrder(
TickerFunctionContext<OrderRequest> context,
CancellationToken cancellationToken)
{
var order = context.Request; // Already typed
}Request Serialization
TickerQ uses GZip-compressed JSON serialization for request data. The TickerHelper handles all serialization automatically.
Job Identification
Function Name
The function name must match exactly between:
[TickerFunction("FunctionName")]attributeFunctionproperty when scheduling
Job ID
Each job gets a unique Guid identifier:
var ticker = new TimeTickerEntity
{
Id = Guid.NewGuid(), // Optional - auto-generated if not set
Function = "MyJob",
// ...
};