HangScheduler is a lightweight job scheduling API built with ASP.NET Core and Hangfire, backed by LiteDB for simple, file-based storage. It provides REST endpoints to schedule, manage, and monitor background jobs, with optional concurrency controls and retry policies.
- Introduction
- Installation
- Usage
- Features
- Dependencies
- Configuration
- Documentation
- Examples
- Troubleshooting
- Contributors
- License
- Clone the repository:
git clone <repository-url>
- Navigate to the project directory:
cd HangScheduler - Restore packages and build:
dotnet restore dotnet build
- Run the application:
dotnet run
Once running, the API exposes endpoints to manage background jobs:
- POST
/jobs/schedule/now: Schedule an immediate job. - POST
/jobs/schedule/now/max_retry: Immediate job with retry on failure. - POST
/jobs/schedule/future: Schedule a job to run at a future date/time. - POST
/jobs/schedule/future/max_retry: Future job with maximum retries. - POST
/jobs/schedule/recurring: Create or update a recurring job. - POST
/jobs/schedule/recurring/max_retry: Create recurring job with retries. - DELETE
/jobs/scheduled/{jobId}: Delete a scheduled job. - DELETE
/jobs/recurring/{jobId}: Delete a recurring job.
Hangfire Dashboard is available at /hangfire.
Swagger UI (API docs) is available at /swagger (non-production environments).
- Schedule one-time or recurring jobs via REST API
- Immediate or future execution
- Optional concurrency control for API calls
- Automatic retry mechanisms
- Built-in API validation (TimeZone, Cron expressions)
- Integrated Hangfire Dashboard for job visualization
- Swagger/OpenAPI support
- Serilog structured logging
Configuration is handled via appsettings.json and environment variables.
Sample appsettings.json snippet:
{
"Serilog": {
"MinimumLevel": "Information",
"WriteTo": [
{ "Name": "Console" }
]
}
}- Swagger UI:
/swagger - Hangfire Dashboard:
/hangfire
curl -X POST "http://localhost:5000/jobs/schedule/now" -H "Content-Type: application/json" -d '{
"ApiEndpoint": "https://your-api.com/execute",
"Payload": {"key":"value"},
"PreventConcurrentExecution": false
}'curl -X POST "http://localhost:5000/jobs/schedule/now/max_retry" -H "Content-Type: application/json" -d '{
"ApiEndpoint": "https://your-api.com/execute",
"Payload": {"key":"value"},
"PreventConcurrentExecution": false
}'curl -X POST "http://localhost:5000/jobs/schedule/future" -H "Content-Type: application/json" -d '{
"ApiEndpoint": "https://your-api.com/execute-later",
"Payload": {"key":"value"},
"ScheduledDateTime": "2025-05-01T15:00:00",
"TimeZoneId": "UTC",
"PreventConcurrentExecution": false
}'curl -X POST "http://localhost:5000/jobs/schedule/future/max_retry" -H "Content-Type: application/json" -d '{
"ApiEndpoint": "https://your-api.com/execute-later",
"Payload": {"key":"value"},
"ScheduledDateTime": "2025-05-01T15:00:00",
"TimeZoneId": "UTC",
"PreventConcurrentExecution": false
}'curl -X POST "http://localhost:5000/jobs/schedule/recurring" -H "Content-Type: application/json" -d '{
"JobId": "my-recurring-job",
"ApiEndpoint": "https://your-api.com/recurring",
"Payload": {"key":"value"},
"CronExpression": "0 * * * *",
"TimeZoneId": "UTC",
"PreventConcurrentExecution": false
}'curl -X POST "http://localhost:5000/jobs/schedule/recurring/max_retry" -H "Content-Type: application/json" -d '{
"JobId": "my-recurring-job-retry",
"ApiEndpoint": "https://your-api.com/recurring-retry",
"Payload": {"key":"value"},
"CronExpression": "0 * * * *",
"TimeZoneId": "UTC",
"PreventConcurrentExecution": false
}'curl -X DELETE "http://localhost:5000/jobs/scheduled/{jobId}"curl -X DELETE "http://localhost:5000/jobs/recurring/{jobId}"Replace {jobId} with your actual job ID.
- Hangfire dashboard not accessible?
Ensure your environment allows
/hangfireendpoint access. - Jobs not running?
Check the database file
hangfire_lite.dband permissions. - Invalid Timezone error?
Verify your system supports the provided
TimeZoneId. - Cron Expression Errors? Validate your cron syntax with an online tool or the API's built-in validation.
- Maintainer: Daniel Pollack
This project is licensed under the MIT License - see the LICENSE file for details.