{"id":47929304,"url":"https://github.com/tomasbasham/escalsched","last_synced_at":"2026-04-04T07:12:08.089Z","repository":{"id":335940127,"uuid":"1146304858","full_name":"tomasbasham/escalsched","owner":"tomasbasham","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-02T01:28:16.000Z","size":24,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-02T08:58:28.650Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomasbasham.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-30T22:26:39.000Z","updated_at":"2026-02-02T01:28:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tomasbasham/escalsched","commit_stats":null,"previous_names":["tomasbasham/escalsched"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/tomasbasham/escalsched","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomasbasham%2Fescalsched","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomasbasham%2Fescalsched/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomasbasham%2Fescalsched/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomasbasham%2Fescalsched/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomasbasham","download_url":"https://codeload.github.com/tomasbasham/escalsched/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomasbasham%2Fescalsched/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31390945,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T04:26:24.776Z","status":"ssl_error","status_checked_at":"2026-04-04T04:23:34.147Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-04T07:12:07.336Z","updated_at":"2026-04-04T07:12:08.075Z","avatar_url":"https://github.com/tomasbasham.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# escalsched [![test](https://github.com/tomasbasham/escalsched/actions/workflows/test.yaml/badge.svg?event=push)](https://github.com/tomasbasham/escalsched/actions/workflows/test.yaml)\n\nA Go scheduler that implements priority-based task scheduling with time-based\nescalation policies. Tasks are processed according to their priority levels,\nwhilst escalation policies ensure that lower-priority tasks don't experience\nindefinite starvation by automatically promoting them when processing delays\nexceed configured thresholds.\n\nThe scheduler provides fairness guarantees through an optional fairness window,\nwhich temporarily suspends priority-based ordering to process tasks in FIFO\norder when the scheduler has been idle, preventing permanent starvation of\nlower-priority work.\n\n## Prerequisites\n\nYou will need the following things properly installed on your computer:\n\n- [Go](https://golang.org/): any one of the **three latest major**\n  [releases](https://golang.org/doc/devel/release.html)\n\n## Installation\n\nWith [Go module](https://go.dev/wiki/Modules) support (Go 1.11+), simply add the\nfollowing import\n\n```go\nimport \"github.com/tomasbasham/escalsched\"\n```\n\nto your code, and then `go [build|run|test]` will automatically fetch the\nnecessary dependencies.\n\nOtherwise, to install the `escalsched` module, run the following command:\n\n```bash\ngo get -u github.com/tomasbasham/escalsched\n```\n\n## Usage\n\nTo use this module, create a scheduler instance and schedule tasks with\npriorities. The scheduler processes tasks in priority order, with\nhigher-priority tasks being unscheduled before lower-priority ones.\n\n### Basic Scheduling\n\n```go\n// Create a new scheduler for string tasks.\nscheduler := escalsched.New[string]()\n\n// Schedule tasks with different priorities.\nscheduler.Schedule(\"low-priority-task\", escalsched.Priorities.Low)\nscheduler.Schedule(\"high-priority-task\", escalsched.Priorities.High)\nscheduler.Schedule(\"normal-priority-task\", escalsched.Priorities.Normal)\n\n// Retrieve the next task (blocks until available).\nctx := context.Background()\ntask := scheduler.Next(ctx)\nfmt.Println(task.Value) // Outputs: \"high-priority-task\"\n```\n\n### Escalation Policies\n\nDefine escalation policies to automatically increase task priority after\nspecified durations:\n\n\u003c!-- pyml disable md013 --\u003e\n```go\nscheduler := escalsched.New[string]()\n\n// Define an escalation policy.\npolicy := escalsched.EscalationPolicy{\n    {After: 100 * time.Millisecond, Target: escalsched.Priorities.High},\n}\n\n// Schedule a task with the policy.\ntask := scheduler.ScheduleWithPolicy(\"important-task\", escalsched.Priorities.Low, policy)\n\n// After 100ms, the task will automatically escalate to High priority if it has\n// not yet been processed.\n```\n\u003c!-- pyml enable md013 --\u003e\n\n### Manual Escalation\n\nTasks can be manually escalated at any time:\n\n```go\nscheduler := escalsched.New[string]()\ntask := scheduler.Schedule(\"task\", escalsched.Priorities.Low)\n\n// Manually escalate to high priority.\nscheduler.Escalate(task, escalsched.Priorities.High)\n```\n\n### Fairness Window\n\nConfigure a fairness window to prevent starvation by temporarily processing\ntasks in FIFO order:\n\n```go\nscheduler := escalsched.New[string](\n    escalsched.WithFairnessWindow(5 * time.Second),\n)\n\n// If the scheduler is idle for 5 seconds, the next task will be unscheduled\n// in FIFO order regardless of priority.\n```\n\n### Metrics Hooks\n\nMonitor scheduler events by implementing the `MetricsHook` interface:\n\n\u003c!-- pyml disable md013 --\u003e\n```go\ntype MyMetrics struct{}\n\nfunc (m *MyMetrics) OnSchedule(task *escalsched.Task[string]) {\n    fmt.Printf(\"Scheduled: %s\\n\", task.Value)\n}\n\nfunc (m *MyMetrics) OnUnschedule(task *escalsched.Task[string]) {\n    fmt.Printf(\"Unscheduled: %s\\n\", task.Value)\n}\n\nfunc (m *MyMetrics) OnEscalate(task *escalsched.Task[string], from, to escalsched.Priority) {\n    fmt.Printf(\"Escalated %s from %s to %s\\n\", task.Value, from, to)\n}\n\nscheduler := escalsched.New[string](\n    escalsched.WithMetricsHook(\u0026MyMetrics{}),\n)\n```\n\u003c!-- pyml enable md013 --\u003e\n\n### Concurrent Workers\n\nThe scheduler is thread-safe and supports multiple concurrent workers:\n\n```go\nscheduler := escalsched.New[int]()\n\n// Schedule tasks.\nfor i := range 100 {\n    scheduler.Schedule(i, escalsched.Priorities.Normal)\n}\n\nnumWorkers := 4\nctx := context.Background()\n\n// Use WaitGroup to know when all workers are done.\nvar wg sync.WaitGroup\nwg.Add(numWorkers)\n\nworker := func(id int) {\n    defer wg.Done()\n    for task := range scheduler.Tasks(ctx)\n        fmt.Printf(\"Worker %d: Processing %d\\n\", w, task.Value)\n    }\n}\n\n// Start workers.\nfor i := range numWorkers {\n    go worker(i + 1)\n}\n\nwg.Wait()\n```\n\n### Unscheduling Tasks\n\nRemove tasks from the scheduler without processing them:\n\n```go\nscheduler := escalsched.New[string]()\ntask := scheduler.Schedule(\"task\", escalsched.Priorities.Normal)\n\n// Remove the task from the scheduler.\nscheduler.UnscheduleTask(task)\n```\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomasbasham%2Fescalsched","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomasbasham%2Fescalsched","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomasbasham%2Fescalsched/lists"}