Skip to content

Commit a88e929

Browse files
committed
docs(admin): clarify support matrix and add admin API examples
1 parent afd2c21 commit a88e929

File tree

18 files changed

+630
-12
lines changed

18 files changed

+630
-12
lines changed

.github/scripts/check_integration_scenarios_contract.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,23 @@ done
6060
echo "Checking backend coverage in integration contract suites..."
6161
backend_pattern() {
6262
local backend="$1"
63+
local backend_const=""
64+
case "${backend}" in
65+
redis) backend_const="BackendRedis" ;;
66+
mysql) backend_const="BackendMySQL" ;;
67+
postgres) backend_const="BackendPostgres" ;;
68+
sqlite) backend_const="BackendSQLite" ;;
69+
nats) backend_const="BackendNATS" ;;
70+
sqs) backend_const="BackendSQS" ;;
71+
rabbitmq) backend_const="BackendRabbitMQ" ;;
72+
*) backend_const="" ;;
73+
esac
74+
75+
if [[ -n "${backend_const}" ]]; then
76+
printf 'integrationBackendEnabled\("%s"\)|integrationBackendEnabled\(testenv\.%s\)|backend:[[:space:]]*"%s"|backend:[[:space:]]*testenv\.%s|name:[[:space:]]*"%s"|name:[[:space:]]*testenv\.%s' "${backend}" "${backend_const}" "${backend}" "${backend_const}" "${backend}" "${backend_const}"
77+
return
78+
fi
79+
6380
printf 'integrationBackendEnabled\("%s"\)|backend:[[:space:]]*"%s"|name:[[:space:]]*"%s"' "${backend}" "${backend}" "${backend}"
6481
}
6582

README.md

Lines changed: 234 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<a href="https://codecov.io/gh/goforj/queue"><img src="https://codecov.io/gh/goforj/queue/graph/badge.svg?token=40Z5UQATME"/></a>
1717
<!-- test-count:embed:start -->
1818
<img src="https://img.shields.io/badge/unit_tests-262-brightgreen" alt="Unit tests (executed count)">
19+
<img src="https://img.shields.io/badge/integration_tests-541-blue" alt="Integration tests (executed count)">
1920
<!-- test-count:embed:end -->
2021
</p>
2122

@@ -62,20 +63,22 @@ func main() {
6263

6364
## Drivers
6465

65-
| Driver / Backend | Mode | Notes | Durable | Async | Delay | Unique | Backoff | Timeout | Native Stats |
66-
| ---: | :--- | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
67-
| <img src="https://img.shields.io/badge/null-%23666?style=flat" alt="Null"> | Drop-only | Discards dispatched jobs; useful for disabled queue modes and smoke tests. | - | - | - | - | - | - | - |
68-
| <img src="https://img.shields.io/badge/sync-%23999999?logo=gnometerminal&logoColor=white" alt="Sync"> | Inline (caller) | Deterministic local execution with no external infra. | - | - | - || - || - |
69-
| <img src="https://img.shields.io/badge/workerpool-%23696969?logo=clockify&logoColor=white" alt="Workerpool"> | In-process pool | Local async behavior without external broker/database. | - |||||| - |
70-
| <img src="https://img.shields.io/badge/mysql-%234479A1?logo=mysql&logoColor=white" alt="MySQL"> | SQL durable queue | MySQL driver module (`driver/mysqlqueue`) built on shared SQL queue core. ||||||||
71-
| <img src="https://img.shields.io/badge/postgres-%23336791?logo=postgresql&logoColor=white" alt="Postgres"> | SQL durable queue | Postgres driver module (`driver/postgresqueue`) built on shared SQL queue core. ||||||||
72-
| <img src="https://img.shields.io/badge/sqlite-%23003B57?logo=sqlite&logoColor=white" alt="SQLite"> | SQL durable queue | SQLite driver module (`driver/sqlitequeue`) built on shared SQL queue core. ||||||||
73-
| <img src="https://img.shields.io/badge/redis-%23DC382D?logo=redis&logoColor=white" alt="Redis"> | Redis/Asynq | Production Redis backend (Asynq semantics). ||||| - |||
74-
| <img src="https://img.shields.io/badge/NATS-007ACC?style=flat" alt="NATS"> | Broker target | NATS transport with queue-subject routing. | - |||||| - |
75-
| <img src="https://img.shields.io/badge/SQS-FF9900?style=flat" alt="SQS"> | Broker target | AWS SQS transport with endpoint overrides for localstack/testing. | - |||||| - |
76-
| <img src="https://img.shields.io/badge/rabbitmq-%23FF6600?logo=rabbitmq&logoColor=white" alt="RabbitMQ"> | Broker target | RabbitMQ transport and worker consumption. | - |||||| - |
66+
| Driver / Backend | Mode | Notes | Durable | Async | Delay | Unique | Backoff | Timeout | Native Stats | Queue Admin |
67+
| ---: | :--- | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
68+
| <img src="https://img.shields.io/badge/null-%23666?style=flat" alt="Null"> | Drop-only | Discards dispatched jobs; useful for disabled queue modes and smoke tests. | - | - | - | - | - | - | - | - |
69+
| <img src="https://img.shields.io/badge/sync-%23999999?logo=gnometerminal&logoColor=white" alt="Sync"> | Inline (caller) | Deterministic local execution with no external infra. | - | - | - || - || - | - |
70+
| <img src="https://img.shields.io/badge/workerpool-%23696969?logo=clockify&logoColor=white" alt="Workerpool"> | In-process pool | Local async behavior without external broker/database. | - |||||| - | - |
71+
| <img src="https://img.shields.io/badge/mysql-%234479A1?logo=mysql&logoColor=white" alt="MySQL"> | SQL durable queue | MySQL driver module (`driver/mysqlqueue`) built on shared SQL queue core. |||||||| - |
72+
| <img src="https://img.shields.io/badge/postgres-%23336791?logo=postgresql&logoColor=white" alt="Postgres"> | SQL durable queue | Postgres driver module (`driver/postgresqueue`) built on shared SQL queue core. |||||||| - |
73+
| <img src="https://img.shields.io/badge/sqlite-%23003B57?logo=sqlite&logoColor=white" alt="SQLite"> | SQL durable queue | SQLite driver module (`driver/sqlitequeue`) built on shared SQL queue core. |||||||| - |
74+
| <img src="https://img.shields.io/badge/redis-%23DC382D?logo=redis&logoColor=white" alt="Redis"> | Redis/Asynq | Production Redis backend (Asynq semantics). ||||| - ||||
75+
| <img src="https://img.shields.io/badge/NATS-007ACC?style=flat" alt="NATS"> | Broker target | NATS transport with queue-subject routing. | - |||||| - | - |
76+
| <img src="https://img.shields.io/badge/SQS-FF9900?style=flat" alt="SQS"> | Broker target | AWS SQS transport with endpoint overrides for localstack/testing. | - |||||| - | - |
77+
| <img src="https://img.shields.io/badge/rabbitmq-%23FF6600?logo=rabbitmq&logoColor=white" alt="RabbitMQ"> | Broker target | RabbitMQ transport and worker consumption. | - |||||| - | - |
7778

7879
> SQL-backed queues (`sqlite`, `mysql`, `postgres`) are durable and convenient, but they trade throughput for operational simplicity. They default to `1` worker, and increasing concurrency may require DB tuning (indexes, connection pool, lock contention). Prefer broker-backed drivers for higher-throughput workloads.
80+
>
81+
> **Queue Admin status:** the cross-driver admin contract is defined in core (`ListJobs`, `RetryJob`, `CancelJob`, `DeleteJob`, `ClearQueue`, `QueueHistory`), but **full queue admin operations are currently implemented only for Redis**. Other drivers return `ErrQueueAdminUnsupported` for unsupported admin actions.
7982
8083
### Driver constructor quick examples
8184

@@ -527,6 +530,12 @@ _ = q
527530
Runnable examples live in the separate `examples` module ([`./examples`](./examples)).
528531
They are not included when applications import `github.com/goforj/queue`, which keeps dependency graphs and build/link overhead smaller.
529532

533+
## Admin Support
534+
535+
Queue admin APIs are part of the core contract so additional drivers can implement them over time.
536+
At this time, full admin operations (`ListJobs`, `RetryJob`, `CancelJob`, `DeleteJob`, `ClearQueue`) are Redis-only.
537+
Use `queue.SupportsQueueAdmin(q)` (or handle `queue.ErrQueueAdminUnsupported`) to gate admin workflows per runtime.
538+
530539
## API reference
531540

532541
The API section below is autogenerated; do not edit between the markers.
@@ -537,6 +546,7 @@ The API section below is autogenerated; do not edit between the markers.
537546

538547
| Group | Functions |
539548
|------:|:-----------|
549+
| **Admin** | [CancelJob](#queue-canceljob) [Queue.CancelJob](#queue-queue-canceljob) [ClearQueue](#queue-clearqueue) [Queue.ClearQueue](#queue-queue-clearqueue) [DeleteJob](#queue-deletejob) [Queue.DeleteJob](#queue-queue-deletejob) [History](#queue-queue-history) [ListJobs](#queue-listjobs) [Queue.ListJobs](#queue-queue-listjobs) [Normalize](#queue-listjobsoptions-normalize) [QueueHistory](#queue-queuehistory) [RetryJob](#queue-retryjob) [Queue.RetryJob](#queue-queue-retryjob) [SinglePointHistory](#queue-singlepointhistory) [SupportsQueueAdmin](#queue-supportsqueueadmin) [TimelineHistoryFromSnapshot](#queue-timelinehistoryfromsnapshot) |
540550
| **Constructors** | [New](#queue-new) [NewNull](#queue-newnull) [NewStatsCollector](#queue-newstatscollector) [NewSync](#queue-newsync) [NewWorkerpool](#queue-newworkerpool) |
541551
| **Job** | [Backoff](#queue-job-backoff) [Bind](#queue-job-bind) [Delay](#queue-job-delay) [NewJob](#queue-newjob) [OnQueue](#queue-job-onqueue) [Payload](#queue-job-payload) [PayloadBytes](#queue-job-payloadbytes) [PayloadJSON](#queue-job-payloadjson) [Retry](#queue-job-retry) [Timeout](#queue-job-timeout) [UniqueFor](#queue-job-uniquefor) |
542552
| **Observability** | [Active](#queue-statssnapshot-active) [Archived](#queue-statssnapshot-archived) [Failed](#queue-statssnapshot-failed) [MultiObserver](#queue-multiobserver) [ChannelObserver.Observe](#queue-channelobserver-observe) [Observer.Observe](#queue-observer-observe) [ObserverFunc.Observe](#queue-observerfunc-observe) [StatsCollector.Observe](#queue-statscollector-observe) [Pause](#queue-pause) [Paused](#queue-statssnapshot-paused) [Pending](#queue-statssnapshot-pending) [Processed](#queue-statssnapshot-processed) [Queue](#queue-statssnapshot-queue) [Queues](#queue-statssnapshot-queues) [Ready](#queue-ready) [Resume](#queue-resume) [RetryCount](#queue-statssnapshot-retrycount) [SafeObserve](#queue-safeobserve) [Scheduled](#queue-statssnapshot-scheduled) [Snapshot](#queue-snapshot) [StatsCollector.Snapshot](#queue-statscollector-snapshot) [SupportsNativeStats](#queue-supportsnativestats) [SupportsPause](#queue-supportspause) [Throughput](#queue-statssnapshot-throughput) |
@@ -548,6 +558,218 @@ The API section below is autogenerated; do not edit between the markers.
548558

549559
## API
550560

561+
#### Admin
562+
563+
#### <a id="queue-canceljob"></a>CancelJob
564+
565+
CancelJob cancels a job when supported.
566+
567+
```go
568+
q, err := redisqueue.New("127.0.0.1:6379")
569+
if err != nil {
570+
return
571+
}
572+
err := queue.CancelJob(context.Background(), q, "job-id")
573+
```
574+
575+
#### <a id="queue-queue-canceljob"></a>Queue.CancelJob
576+
577+
CancelJob cancels a job via queue admin capability when supported.
578+
579+
```go
580+
q, err := redisqueue.New("127.0.0.1:6379")
581+
if err != nil {
582+
return
583+
}
584+
err := q.CancelJob(context.Background(), "job-id")
585+
```
586+
587+
#### <a id="queue-clearqueue"></a>ClearQueue
588+
589+
ClearQueue clears queue jobs when supported.
590+
591+
```go
592+
q, err := redisqueue.New("127.0.0.1:6379")
593+
if err != nil {
594+
return
595+
}
596+
err := queue.ClearQueue(context.Background(), q, "default")
597+
```
598+
599+
#### <a id="queue-queue-clearqueue"></a>Queue.ClearQueue
600+
601+
ClearQueue clears queue jobs via queue admin capability when supported.
602+
603+
```go
604+
q, err := redisqueue.New("127.0.0.1:6379")
605+
if err != nil {
606+
return
607+
}
608+
err := q.ClearQueue(context.Background(), "default")
609+
```
610+
611+
#### <a id="queue-deletejob"></a>DeleteJob
612+
613+
DeleteJob deletes a job when supported.
614+
615+
```go
616+
q, err := redisqueue.New("127.0.0.1:6379")
617+
if err != nil {
618+
return
619+
}
620+
err := queue.DeleteJob(context.Background(), q, "default", "job-id")
621+
```
622+
623+
#### <a id="queue-queue-deletejob"></a>Queue.DeleteJob
624+
625+
DeleteJob deletes a job via queue admin capability when supported.
626+
627+
```go
628+
q, err := redisqueue.New("127.0.0.1:6379")
629+
if err != nil {
630+
return
631+
}
632+
err := q.DeleteJob(context.Background(), "default", "job-id")
633+
```
634+
635+
#### <a id="queue-queue-history"></a>History
636+
637+
History returns queue history points via queue admin capability when supported.
638+
639+
```go
640+
q, err := redisqueue.New("127.0.0.1:6379")
641+
if err != nil {
642+
return
643+
}
644+
points, err := q.History(context.Background(), "default", queue.QueueHistoryHour)
645+
_ = err
646+
```
647+
648+
#### <a id="queue-listjobs"></a>ListJobs
649+
650+
ListJobs lists jobs for a queue and state when supported.
651+
652+
```go
653+
q, err := redisqueue.New("127.0.0.1:6379")
654+
if err != nil {
655+
return
656+
}
657+
_, err := queue.ListJobs(context.Background(), q, queue.ListJobsOptions{
658+
Queue: "default",
659+
State: queue.JobStatePending,
660+
})
661+
_ = err
662+
```
663+
664+
#### <a id="queue-queue-listjobs"></a>Queue.ListJobs
665+
666+
ListJobs lists jobs via queue admin capability when supported.
667+
668+
```go
669+
q, err := redisqueue.New("127.0.0.1:6379")
670+
if err != nil {
671+
return
672+
}
673+
_, err := q.ListJobs(context.Background(), queue.ListJobsOptions{
674+
Queue: "default",
675+
State: queue.JobStatePending,
676+
})
677+
_ = err
678+
```
679+
680+
#### <a id="queue-listjobsoptions-normalize"></a>Normalize
681+
682+
Normalize returns a safe options payload with defaults applied.
683+
684+
```go
685+
opts := queue.ListJobsOptions{Queue: "", State: "", Page: 0, PageSize: 1000}
686+
normalized := opts.Normalize()
687+
fmt.Println(normalized.Queue, normalized.State, normalized.Page, normalized.PageSize)
688+
// Output: default pending 1 500
689+
```
690+
691+
#### <a id="queue-queuehistory"></a>QueueHistory
692+
693+
QueueHistory returns queue history points when supported.
694+
695+
```go
696+
q, err := redisqueue.New("127.0.0.1:6379")
697+
if err != nil {
698+
return
699+
}
700+
_, err := queue.QueueHistory(context.Background(), q, "default", queue.QueueHistoryHour)
701+
_ = err
702+
```
703+
704+
#### <a id="queue-retryjob"></a>RetryJob
705+
706+
RetryJob retries (runs now) a job when supported.
707+
708+
```go
709+
q, err := redisqueue.New("127.0.0.1:6379")
710+
if err != nil {
711+
return
712+
}
713+
err := queue.RetryJob(context.Background(), q, "default", "job-id")
714+
```
715+
716+
#### <a id="queue-queue-retryjob"></a>Queue.RetryJob
717+
718+
RetryJob retries (runs now) a job via queue admin capability when supported.
719+
720+
```go
721+
q, err := redisqueue.New("127.0.0.1:6379")
722+
if err != nil {
723+
return
724+
}
725+
err := q.RetryJob(context.Background(), "default", "job-id")
726+
```
727+
728+
#### <a id="queue-singlepointhistory"></a>SinglePointHistory
729+
730+
SinglePointHistory converts a snapshot into a single current-history point.
731+
This helper is intended for driver modules that do not expose historical buckets.
732+
733+
```go
734+
snapshot := queue.StatsSnapshot{
735+
ByQueue: map[string]queue.QueueCounters{
736+
"default": {Processed: 12, Failed: 1},
737+
},
738+
}
739+
points := queue.SinglePointHistory(snapshot, "default")
740+
fmt.Println(len(points), points[0].Processed, points[0].Failed)
741+
// Output: 1 12 1
742+
```
743+
744+
#### <a id="queue-supportsqueueadmin"></a>SupportsQueueAdmin
745+
746+
SupportsQueueAdmin reports whether queue admin operations are available.
747+
748+
```go
749+
q, err := redisqueue.New("127.0.0.1:6379")
750+
if err != nil {
751+
return
752+
}
753+
fmt.Println(queue.SupportsQueueAdmin(q))
754+
// Output: true
755+
```
756+
757+
#### <a id="queue-timelinehistoryfromsnapshot"></a>TimelineHistoryFromSnapshot
758+
759+
TimelineHistoryFromSnapshot records queue counters and returns windowed points.
760+
This is intended for drivers that don't expose native multi-point history.
761+
762+
```go
763+
snapshot := queue.StatsSnapshot{
764+
ByQueue: map[string]queue.QueueCounters{
765+
"default": {Processed: 5, Failed: 1},
766+
},
767+
}
768+
points := queue.TimelineHistoryFromSnapshot(snapshot, "default", queue.QueueHistoryHour)
769+
fmt.Println(len(points) >= 1)
770+
// Output: true
771+
```
772+
551773
#### Constructors
552774

553775
#### <a id="queue-new"></a>queue.New

examples/canceljob/main.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//go:build ignore
2+
// +build ignore
3+
4+
// examplegen:generated
5+
6+
package main
7+
8+
import (
9+
"context"
10+
"github.com/goforj/queue"
11+
)
12+
13+
func main() {
14+
// CancelJob cancels a job when supported.
15+
16+
// Example: cancel a job via helper
17+
q, err := redisqueue.New("127.0.0.1:6379")
18+
if err != nil {
19+
return
20+
}
21+
err := queue.CancelJob(context.Background(), q, "job-id")
22+
_ = err
23+
}

examples/clearqueue/main.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//go:build ignore
2+
// +build ignore
3+
4+
// examplegen:generated
5+
6+
package main
7+
8+
import (
9+
"context"
10+
"github.com/goforj/queue"
11+
)
12+
13+
func main() {
14+
// ClearQueue clears queue jobs when supported.
15+
16+
// Example: clear queue via helper
17+
q, err := redisqueue.New("127.0.0.1:6379")
18+
if err != nil {
19+
return
20+
}
21+
err := queue.ClearQueue(context.Background(), q, "default")
22+
_ = err
23+
}

examples/deletejob/main.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//go:build ignore
2+
// +build ignore
3+
4+
// examplegen:generated
5+
6+
package main
7+
8+
import (
9+
"context"
10+
"github.com/goforj/queue"
11+
)
12+
13+
func main() {
14+
// DeleteJob deletes a job when supported.
15+
16+
// Example: delete a job via helper
17+
q, err := redisqueue.New("127.0.0.1:6379")
18+
if err != nil {
19+
return
20+
}
21+
err := queue.DeleteJob(context.Background(), q, "default", "job-id")
22+
_ = err
23+
}

0 commit comments

Comments
 (0)