diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 82a81fc..f77eade 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -2,11 +2,9 @@ name: Test
on:
push:
- branches: [ main, master ]
- tags:
- - 'v*'
+ branches: [ develop ]
pull_request:
- branches: [ master ]
+ branches: [ develop ]
jobs:
test:
diff --git a/.gitignore b/.gitignore
index 496ee2c..152b132 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-.DS_Store
\ No newline at end of file
+.DS_Store
+.tmp*
diff --git a/README.md b/README.md
index aa43802..0f6159a 100644
--- a/README.md
+++ b/README.md
@@ -1,66 +1,54 @@
> [!NOTE]
-> This README was generated by [SKILL](https://github.com/pardnchiu/skill-readme-generate), get the ZH version from [here](./README.zh.md).
+> This README was generated by [SKILL](https://github.com/agenvoy/skill-readme-generate), get the ZH version from [here](./doc/README.zh.md).
-# go-queue
+***
+
+
+PRIORITY-AWARE TASK QUEUE FOR GO
+
-[](https://pkg.go.dev/github.com/pardnchiu/go-queue)
-[](https://goreportcard.com/report/github.com/pardnchiu/go-queue)
-[](https://app.codecov.io/github/pardnchiu/go-queue/tree/master)
-[](LICENSE)
-[](https://github.com/pardnchiu/go-queue/releases)
+
+
+
+
+
+
+
+***
-> A min-heap based priority task queue with automatic promotion, retry, and panic recovery, designed for Go concurrency workloads.
+> A Go task queue library with priority scheduling, timeout retries, and an atomic state machine
## Table of Contents
- [Features](#features)
- [Architecture](#architecture)
-- [File Structure](#file-structure)
- [License](#license)
- [Author](#author)
-- [Stars](#stars)
## Features
-> `go get github.com/pardnchiu/go-queue` · [Documentation](./doc.md)
-
-### Five-Level Priority Scheduling with Auto-Promotion
-
-Tasks are scheduled through a min-heap across five priority levels: Immediate, High, Retry, Normal, and Low. Low-priority tasks automatically promote to higher levels after exceeding a configurable wait threshold, eliminating starvation without manual intervention.
-
-### Atomic State Machine Lifecycle
-
-Queue state transitions from Created to Running to Closed are driven entirely by `atomic.CompareAndSwap`, avoiding mutexes on the Start and Shutdown paths. This ensures safe concurrent access from multiple goroutines with minimal latency.
+> `go get github.com/pardnchiu/go-queue` · [Documentation](./doc/doc.md)
-### Built-in Retry with Panic Recovery
-
-Each task supports a configurable retry limit; failed tasks re-enter the heap at Retry priority. Workers automatically recover from panics and convert them to error reports, preventing a single task crash from taking down the entire worker pool.
+- **Five-Level Priority Queue** — Orders Immediate, High, Retry, Normal, and Low tasks, with automatic promotion after wait timeouts.
+- **Worker Pool Parallelism** — Defaults to CPU×2 workers with configurable queue capacity and global timeout.
+- **Timeout and Retry** — Isolates panics, enforces per-task timeouts, and re-enqueues failed tasks at the highest priority.
+- **Functional Options** — Configures each enqueue with WithTaskID, WithTimeout, WithCallback, and WithRetry.
+- **Atomic State Machine** — Transitions Created, Running, and Closed via CAS for lock-free, idempotent Shutdown.
## Architecture
+> [Full Architecture](./doc/architecture.md)
+
```mermaid
graph TB
- E[Enqueue] -->|Push| H[Min-Heap]
- H -->|Pop| W[Worker Pool]
- W -->|Execute| T[Task]
- T -->|Fail + Retry| H
- H -->|Promote| H
- T -->|Success| CB[Callback]
- T -->|Panic| R[Recovery → Error]
-```
-
-## File Structure
-
-```
-go-queue/
-├── new.go # Queue construction, worker startup and shutdown
-├── task.go # Task struct and min-heap implementation
-├── pending.go # Pending queue, push/pop and auto-promotion
-├── priority.go # Priority level definitions and timeout calculation
-├── option.go # Enqueue options (TaskID, Timeout, Callback, Retry)
-├── main_test.go # Tests
-├── go.mod
-└── LICENSE
+ App[Application] --> Enqueue[Enqueue]
+ Enqueue --> Pending[Pending Heap]
+ Pending --> Workers[Worker Pool]
+ Workers --> Execute[Execute / Timeout / Retry]
+ App --> Start[Start]
+ App --> Shutdown[Shutdown]
+ Start --> Workers
+ Shutdown --> Pending
```
## License
@@ -69,20 +57,13 @@ This project is licensed under the [MIT LICENSE](LICENSE).
## Author
-
+
邱敬幃 Pardn Chiu
-
-
-
-
-
-
-## Stars
-
-[](https://www.star-history.com/#pardnchiu/go-queue&Date)
+hi@pardn.io
+https://www.linkedin.com/in/pardnchiu
***
-©️ 2025 [邱敬幃 Pardn Chiu](https://linkedin.com/in/pardnchiu)
+©️ 2025 [邱敬幃 Pardn Chiu](https://www.linkedin.com/in/pardnchiu)
diff --git a/README.zh.md b/README.zh.md
deleted file mode 100644
index 1f60cfb..0000000
--- a/README.zh.md
+++ /dev/null
@@ -1,88 +0,0 @@
-> [!NOTE]
-> 此 README 由 [SKILL](https://github.com/pardnchiu/skill-readme-generate) 生成,英文版請參閱 [這裡](./README.md)。
-
-# go-queue
-
-[](https://pkg.go.dev/github.com/pardnchiu/go-queue)
-[](https://goreportcard.com/report/github.com/pardnchiu/go-queue)
-[](https://app.codecov.io/github/pardnchiu/go-queue/tree/master)
-[](LICENSE)
-[](https://github.com/pardnchiu/go-queue/releases)
-
-> 基於 Min-Heap 的優先任務佇列,支援自動升級、Retry 與 Panic Recovery,專為 Go 併發場景設計。
-
-## 目錄
-
-- [功能特點](#功能特點)
-- [架構](#架構)
-- [檔案結構](#檔案結構)
-- [授權](#授權)
-- [Author](#author)
-- [Stars](#stars)
-
-## 功能特點
-
-> `go get github.com/pardnchiu/go-queue` · [完整文件](./doc.zh.md)
-
-### 五級優先排程與自動升級
-
-任務依 Immediate、High、Retry、Normal、Low 五個等級透過 Min-Heap 排程,低優先任務在等待超過閾值後自動升級至更高等級,從根本上消除 Starvation 問題,無需手動干預。
-
-### Atomic 狀態機驅動生命週期
-
-佇列的 Created → Running → Closed 狀態轉換完全透過 `atomic.CompareAndSwap` 實現,避免在 Start 和 Shutdown 路徑上使用 Mutex,確保多個 Goroutine 同時操作時的安全性與低延遲。
-
-### 內建 Retry 與 Panic Recovery
-
-每個任務可配置獨立的重試次數上限,失敗後以 Retry 優先級重新入列。Worker 層自動攔截 Panic 並轉為錯誤回報,防止單一任務崩潰拖垮整個 Worker Pool。
-
-## 架構
-
-```mermaid
-graph TB
- E[Enqueue] -->|Push| H[Min-Heap]
- H -->|Pop| W[Worker Pool]
- W -->|Execute| T[Task]
- T -->|Fail + Retry| H
- H -->|Promote| H
- T -->|Success| CB[Callback]
- T -->|Panic| R[Recovery → Error]
-```
-
-## 檔案結構
-
-```
-go-queue/
-├── new.go # 佇列建構、Worker 啟動與 Shutdown
-├── task.go # 任務結構與 Min-Heap 實作
-├── pending.go # 等待佇列、Push/Pop 與自動升級
-├── priority.go # 優先等級定義與 Timeout 計算
-├── option.go # Enqueue 選項(TaskID、Timeout、Callback、Retry)
-├── main_test.go # 測試
-├── go.mod
-└── LICENSE
-```
-
-## 授權
-
-本專案採用 [MIT LICENSE](LICENSE)。
-
-## Author
-
-
-
-邱敬幃 Pardn Chiu
-
-
-
-
-
-
-
-## Stars
-
-[](https://www.star-history.com/#pardnchiu/go-queue&Date)
-
-***
-
-©️ 2025 [邱敬幃 Pardn Chiu](https://linkedin.com/in/pardnchiu)
diff --git a/main_test.go b/core/main_test.go
similarity index 99%
rename from main_test.go
rename to core/main_test.go
index 69474d5..a285426 100644
--- a/main_test.go
+++ b/core/main_test.go
@@ -1,5 +1,5 @@
// * generated by claude sonnet 4.5
-package goQueue
+package core
import (
"context"
diff --git a/new.go b/core/new.go
similarity index 99%
rename from new.go
rename to core/new.go
index 6fbf7b2..f660b0d 100644
--- a/new.go
+++ b/core/new.go
@@ -1,4 +1,4 @@
-package goQueue
+package core
import (
"context"
diff --git a/option.go b/core/option.go
similarity index 97%
rename from option.go
rename to core/option.go
index 6e51417..520da8a 100644
--- a/option.go
+++ b/core/option.go
@@ -1,4 +1,4 @@
-package goQueue
+package core
import "time"
diff --git a/pending.go b/core/pending.go
similarity index 99%
rename from pending.go
rename to core/pending.go
index 16226a9..3194d65 100644
--- a/pending.go
+++ b/core/pending.go
@@ -1,4 +1,4 @@
-package goQueue
+package core
import (
"container/heap"
diff --git a/priority.go b/core/priority.go
similarity index 97%
rename from priority.go
rename to core/priority.go
index 0859d18..043ac94 100644
--- a/priority.go
+++ b/core/priority.go
@@ -1,4 +1,4 @@
-package goQueue
+package core
import (
"time"
diff --git a/task.go b/core/task.go
similarity index 98%
rename from task.go
rename to core/task.go
index 737faf6..ea136bf 100644
--- a/task.go
+++ b/core/task.go
@@ -1,4 +1,4 @@
-package goQueue
+package core
import (
"context"
diff --git a/cover.png b/cover.png
deleted file mode 100644
index 7377fd5..0000000
Binary files a/cover.png and /dev/null differ
diff --git a/doc.md b/doc.md
deleted file mode 100644
index 1bc622b..0000000
--- a/doc.md
+++ /dev/null
@@ -1,226 +0,0 @@
-# go-queue - Documentation
-
-> Back to [README](./README.md)
-
-## Prerequisites
-
-- Go 1.23 or higher
-
-## Installation
-
-### Using go get
-
-```bash
-go get github.com/pardnchiu/go-queue
-```
-
-### From Source
-
-```bash
-git clone https://github.com/pardnchiu/go-queue.git
-cd go-queue
-go test ./...
-```
-
-## Usage
-
-### Basic
-
-Create a queue, start workers, and submit tasks:
-
-```go
-package main
-
-import (
- "context"
- "fmt"
- "log"
-
- goQueue "github.com/pardnchiu/go-queue"
-)
-
-func main() {
- q := goQueue.New(&goQueue.Config{
- Workers: 4,
- })
-
- ctx := context.Background()
- if err := q.Start(ctx); err != nil {
- log.Fatal(err)
- }
-
- id, err := q.Enqueue(ctx, "", func(ctx context.Context) error {
- fmt.Println("task executed")
- return nil
- })
- if err != nil {
- log.Fatal(err)
- }
- fmt.Println("task id:", id)
-
- if err := q.Shutdown(ctx); err != nil {
- log.Fatal(err)
- }
-}
-```
-
-### Presets and Priority
-
-Define task types with preset priority and timeout:
-
-```go
-q := goQueue.New(&goQueue.Config{
- Workers: 4,
- Timeout: 30 * time.Second,
- Preset: map[string]goQueue.PresetConfig{
- "critical": {Priority: goQueue.PriorityImmediate},
- "batch": {Priority: goQueue.PriorityLow, Timeout: 60 * time.Second},
- },
-})
-
-ctx := context.Background()
-q.Start(ctx)
-
-// Enqueue with Immediate priority
-q.Enqueue(ctx, "critical", func(ctx context.Context) error {
- // High priority task
- return nil
-})
-
-// Enqueue with Low priority, 60s timeout
-q.Enqueue(ctx, "batch", func(ctx context.Context) error {
- // Low priority batch task
- return nil
-})
-
-q.Shutdown(ctx)
-```
-
-### Retry and Callback
-
-Configure retry and completion callback for tasks:
-
-```go
-q := goQueue.New(&goQueue.Config{Workers: 2})
-ctx := context.Background()
-q.Start(ctx)
-
-id, err := q.Enqueue(ctx, "", func(ctx context.Context) error {
- // Operation that may fail
- return doSomething()
-},
- goQueue.WithRetry(3), // Retry up to 3 times
- goQueue.WithTaskID("my-task-001"), // Custom task ID
- goQueue.WithTimeout(10*time.Second), // Per-task timeout
- goQueue.WithCallback(func(id string) { // Completion callback
- fmt.Printf("task %s completed\n", id)
- }),
-)
-if err != nil {
- log.Fatal(err)
-}
-
-q.Shutdown(ctx)
-```
-
-### Graceful Shutdown with Timeout
-
-Limit shutdown wait time to prevent indefinite blocking:
-
-```go
-q := goQueue.New(&goQueue.Config{Workers: 4})
-ctx := context.Background()
-q.Start(ctx)
-
-// ... submit tasks ...
-
-shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
-defer cancel()
-
-if err := q.Shutdown(shutdownCtx); err != nil {
- fmt.Printf("shutdown timeout: %v\n", err)
-}
-```
-
-## API Reference
-
-### New
-
-```go
-func New(config *Config) *Queue
-```
-
-Create a new queue instance. Passing `nil` for config uses default values.
-
-### Config
-
-```go
-type Config struct {
- Workers int // Number of workers, default CPU * 2
- Size int // Queue capacity limit, default Workers * 64
- Timeout time.Duration // Global task timeout, default 30s
- Preset map[string]PresetConfig // Task type preset configurations
-}
-```
-
-### PresetConfig
-
-```go
-type PresetConfig struct {
- Priority Priority // Priority level, default PriorityNormal
- Timeout time.Duration // Task timeout, 0 = auto-calculated by Priority
-}
-```
-
-### Priority
-
-```go
-type Priority int
-
-const (
- PriorityImmediate Priority = iota // Highest priority
- PriorityHigh // High priority
- PriorityRetry // Reserved for retried tasks
- PriorityNormal // Normal (default)
- PriorityLow // Low priority
-)
-```
-
-Priority affects timeout calculation: Immediate = base/4, High = base/2, Normal = base, Low = base*2, clamped to the 15~120 second range.
-
-### Queue.Start
-
-```go
-func (q *Queue) Start(ctx context.Context) error
-```
-
-Start the worker pool. Returns an error if called again or if the queue is already closed.
-
-### Queue.Enqueue
-
-```go
-func (q *Queue) Enqueue(ctx context.Context, presetName string, action func(ctx context.Context) error, options ...EnqueueOption) (string, error)
-```
-
-Submit a task to the queue. `presetName` maps to a key in `Config.Preset`; an empty string uses defaults. Returns the task ID or an error (context cancelled, queue full, or queue closed).
-
-### Queue.Shutdown
-
-```go
-func (q *Queue) Shutdown(ctx context.Context) error
-```
-
-Close the queue and wait for all workers to finish. Returns an error with the remaining task count if the context times out.
-
-### EnqueueOption
-
-| Function | Signature | Description |
-|----------|-----------|-------------|
-| `WithTaskID` | `func WithTaskID(id string) EnqueueOption` | Set a custom task ID; defaults to auto-generated UUID v4 |
-| `WithTimeout` | `func WithTimeout(d time.Duration) EnqueueOption` | Override per-task timeout |
-| `WithCallback` | `func WithCallback(fn func(id string)) EnqueueOption` | Callback invoked after successful task completion |
-| `WithRetry` | `func WithRetry(retryMax ...int) EnqueueOption` | Enable retry with default max 3; optionally specify limit |
-
-***
-
-©️ 2025 [邱敬幃 Pardn Chiu](https://linkedin.com/in/pardnchiu)
diff --git a/doc.zh.md b/doc.zh.md
deleted file mode 100644
index 414c804..0000000
--- a/doc.zh.md
+++ /dev/null
@@ -1,226 +0,0 @@
-# go-queue - 技術文件
-
-> 返回 [README](./README.zh.md)
-
-## 前置需求
-
-- Go 1.23 或更高版本
-
-## 安裝
-
-### 使用 go get
-
-```bash
-go get github.com/pardnchiu/go-queue
-```
-
-### 從原始碼建置
-
-```bash
-git clone https://github.com/pardnchiu/go-queue.git
-cd go-queue
-go test ./...
-```
-
-## 使用方式
-
-### 基礎用法
-
-建立佇列、啟動 Worker 並提交任務:
-
-```go
-package main
-
-import (
- "context"
- "fmt"
- "log"
-
- goQueue "github.com/pardnchiu/go-queue"
-)
-
-func main() {
- q := goQueue.New(&goQueue.Config{
- Workers: 4,
- })
-
- ctx := context.Background()
- if err := q.Start(ctx); err != nil {
- log.Fatal(err)
- }
-
- id, err := q.Enqueue(ctx, "", func(ctx context.Context) error {
- fmt.Println("task executed")
- return nil
- })
- if err != nil {
- log.Fatal(err)
- }
- fmt.Println("task id:", id)
-
- if err := q.Shutdown(ctx); err != nil {
- log.Fatal(err)
- }
-}
-```
-
-### 使用 Preset 與優先級
-
-透過 Preset 預定義不同任務類型的優先級與 Timeout:
-
-```go
-q := goQueue.New(&goQueue.Config{
- Workers: 4,
- Timeout: 30 * time.Second,
- Preset: map[string]goQueue.PresetConfig{
- "critical": {Priority: goQueue.PriorityImmediate},
- "batch": {Priority: goQueue.PriorityLow, Timeout: 60 * time.Second},
- },
-})
-
-ctx := context.Background()
-q.Start(ctx)
-
-// 以 Immediate 優先級入列
-q.Enqueue(ctx, "critical", func(ctx context.Context) error {
- // 高優先任務
- return nil
-})
-
-// 以 Low 優先級入列,Timeout 60 秒
-q.Enqueue(ctx, "batch", func(ctx context.Context) error {
- // 低優先批次任務
- return nil
-})
-
-q.Shutdown(ctx)
-```
-
-### 使用 Retry 與 Callback
-
-為任務配置重試機制與完成回呼:
-
-```go
-q := goQueue.New(&goQueue.Config{Workers: 2})
-ctx := context.Background()
-q.Start(ctx)
-
-id, err := q.Enqueue(ctx, "", func(ctx context.Context) error {
- // 可能失敗的操作
- return doSomething()
-},
- goQueue.WithRetry(3), // 最多重試 3 次
- goQueue.WithTaskID("my-task-001"), // 自訂任務 ID
- goQueue.WithTimeout(10*time.Second), // 任務級 Timeout
- goQueue.WithCallback(func(id string) { // 完成回呼
- fmt.Printf("task %s completed\n", id)
- }),
-)
-if err != nil {
- log.Fatal(err)
-}
-
-q.Shutdown(ctx)
-```
-
-### Graceful Shutdown 與 Timeout
-
-限制 Shutdown 等待時間,避免無限阻塞:
-
-```go
-q := goQueue.New(&goQueue.Config{Workers: 4})
-ctx := context.Background()
-q.Start(ctx)
-
-// ... 提交任務 ...
-
-shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
-defer cancel()
-
-if err := q.Shutdown(shutdownCtx); err != nil {
- fmt.Printf("shutdown timeout: %v\n", err)
-}
-```
-
-## API 參考
-
-### New
-
-```go
-func New(config *Config) *Queue
-```
-
-建立新的佇列實例。`config` 為 `nil` 時使用預設值。
-
-### Config
-
-```go
-type Config struct {
- Workers int // Worker 數量,預設 CPU * 2
- Size int // 佇列容量上限,預設 Workers * 64
- Timeout time.Duration // 全域任務 Timeout,預設 30 秒
- Preset map[string]PresetConfig // 任務類型預設配置
-}
-```
-
-### PresetConfig
-
-```go
-type PresetConfig struct {
- Priority Priority // 優先等級,預設 PriorityNormal
- Timeout time.Duration // 任務 Timeout,0 = 依 Priority 自動計算
-}
-```
-
-### Priority
-
-```go
-type Priority int
-
-const (
- PriorityImmediate Priority = iota // 最高優先
- PriorityHigh // 高優先
- PriorityRetry // 重試任務專用
- PriorityNormal // 一般(預設)
- PriorityLow // 低優先
-)
-```
-
-Priority 影響 Timeout 計算:Immediate = base/4、High = base/2、Normal = base、Low = base*2,最終限制在 15~120 秒區間。
-
-### Queue.Start
-
-```go
-func (q *Queue) Start(ctx context.Context) error
-```
-
-啟動 Worker Pool。重複呼叫或佇列已關閉時回傳錯誤。
-
-### Queue.Enqueue
-
-```go
-func (q *Queue) Enqueue(ctx context.Context, presetName string, action func(ctx context.Context) error, options ...EnqueueOption) (string, error)
-```
-
-提交任務至佇列。`presetName` 對應 `Config.Preset` 中的鍵,空字串使用預設值。回傳任務 ID 或錯誤(Context 已取消、佇列已滿或已關閉)。
-
-### Queue.Shutdown
-
-```go
-func (q *Queue) Shutdown(ctx context.Context) error
-```
-
-關閉佇列並等待所有 Worker 完成。Context 超時時回傳剩餘任務數量的錯誤。
-
-### EnqueueOption
-
-| 函式 | 簽章 | 說明 |
-|------|------|------|
-| `WithTaskID` | `func WithTaskID(id string) EnqueueOption` | 自訂任務 ID,預設自動產生 UUID v4 |
-| `WithTimeout` | `func WithTimeout(d time.Duration) EnqueueOption` | 覆寫任務級 Timeout |
-| `WithCallback` | `func WithCallback(fn func(id string)) EnqueueOption` | 任務成功完成後的回呼函式 |
-| `WithRetry` | `func WithRetry(retryMax ...int) EnqueueOption` | 啟用重試,預設最多 3 次;可指定上限 |
-
-***
-
-©️ 2025 [邱敬幃 Pardn Chiu](https://linkedin.com/in/pardnchiu)
diff --git a/doc/README.zh.md b/doc/README.zh.md
new file mode 100644
index 0000000..54b79dc
--- /dev/null
+++ b/doc/README.zh.md
@@ -0,0 +1,69 @@
+> [!NOTE]
+> 此 README 由 [SKILL](https://github.com/agenvoy/skill-readme-generate) 生成,英文版請參閱 [這裡](../README.md)。
+
+***
+
+
+PRIORITY-AWARE TASK QUEUE FOR GO
+
+
+
+
+
+
+
+
+
+***
+
+> Go 任務佇列函式庫,具備優先級排程、逾時重試與原子狀態機
+
+## 目錄
+
+- [功能特點](#功能特點)
+- [架構](#架構)
+- [授權](#授權)
+- [Author](#author)
+
+## 功能特點
+
+> `go get github.com/pardnchiu/go-queue` · [完整文件](./doc.zh.md)
+
+- **五級優先佇列** — Immediate/High/Retry/Normal/Low 排序,低優先級逾時後自動晉升。
+- **Worker 池並行** — 預設 CPU×2 個 worker,可調佇列容量與全域逾時。
+- **逾時與重試** — 任務逾時、panic 隔離、可設定重試次數並以最高優先級重新入隊。
+- **Functional Options** — WithTaskID、WithTimeout、WithCallback、WithRetry 彈性設定單次入隊。
+- **原子狀態機** — Created/Running/Closed 以 CAS 轉換,冪等 Shutdown 且無 mutex 競爭。
+
+## 架構
+
+> [完整架構](./architecture.zh.md)
+
+```mermaid
+graph TB
+ App[應用程式] --> Enqueue[Enqueue]
+ Enqueue --> Pending[待處理 Heap]
+ Pending --> Workers[Worker 池]
+ Workers --> Execute[執行 / 逾時 / 重試]
+ App --> Start[Start]
+ App --> Shutdown[Shutdown]
+ Start --> Workers
+ Shutdown --> Pending
+```
+
+## 授權
+
+本專案採用 [MIT LICENSE](../LICENSE)。
+
+## Author
+
+
+
+邱敬幃 Pardn Chiu
+
+hi@pardn.io
+https://www.linkedin.com/in/pardnchiu
+
+***
+
+©️ 2025 [邱敬幃 Pardn Chiu](https://www.linkedin.com/in/pardnchiu)
diff --git a/doc/architecture.md b/doc/architecture.md
new file mode 100644
index 0000000..7781673
--- /dev/null
+++ b/doc/architecture.md
@@ -0,0 +1,136 @@
+# go-queue - Architecture
+
+> Back to [README](../README.md)
+
+## Overview
+
+```mermaid
+graph TB
+ App[Application] --> Enqueue[Enqueue]
+ App --> Start[Start]
+ App --> Shutdown[Shutdown]
+ Enqueue --> Pending[Pending Heap]
+ Start --> Workers[Worker Pool]
+ Pending --> Workers
+ Workers --> Execute[Execute / Timeout / Retry]
+ Shutdown --> Pending
+ Shutdown --> Workers
+```
+
+## Module: Queue
+
+Public API and lifecycle entry point. Owns config, pending queue, and worker coordination.
+
+```mermaid
+graph TB
+ subgraph Queue
+ New[New] --> Config[Config / Preset]
+ New --> Pending[pending]
+ Start[Start] --> Workers[worker goroutines]
+ Enqueue[Enqueue] --> Options[EnqueueOption]
+ Enqueue --> Pending
+ Workers --> Execute[execute]
+ Execute --> Retry[setRetry]
+ Retry --> Pending
+ Shutdown[Shutdown] --> Close[pending.Close]
+ Shutdown --> Wait[WaitGroup]
+ end
+ App[Caller] --> New
+ App --> Start
+ App --> Enqueue
+ App --> Shutdown
+```
+
+## Module: pending
+
+Mutex + condition-variable protected priority queue with promotion and close broadcast.
+
+```mermaid
+graph TB
+ subgraph pending
+ Push[Push] --> Heap[taskHeap]
+ Pop[Pop] --> Promote[promoteLocked]
+ Promote --> Heap
+ Pop --> Heap
+ Close[Close] --> Broadcast[cond.Broadcast]
+ Len[Len] --> Heap
+ end
+ Queue[Queue] --> Push
+ Queue --> Pop
+ Queue --> Close
+```
+
+## Module: taskHeap
+
+`container/heap` ordered by priority then `startAt`, with capacity shrink on pop.
+
+```mermaid
+classDiagram
+ class task {
+ +string ID
+ +string preset
+ +Priority priority
+ +func action
+ +Duration timeout
+ +func callback
+ +Time startAt
+ +bool retryOn
+ +int retryMax
+ +int retryTimes
+ }
+ class taskHeap {
+ +taskHeaps tasks
+ +int minCap
+ +Len()
+ +Less()
+ +Swap()
+ +Push()
+ +Pop()
+ }
+ taskHeap --> task : holds
+```
+
+## Data Flow
+
+```mermaid
+sequenceDiagram
+ participant App as Application
+ participant Q as Queue
+ participant P as pending
+ participant W as Worker
+ participant T as task action
+
+ App->>Q: New(config)
+ App->>Q: Start(ctx)
+ Q->>W: spawn workers
+ App->>Q: Enqueue(preset, action, opts)
+ Q->>P: Push(task)
+ P-->>W: Pop(task, promotions)
+ W->>T: action(ctx with timeout)
+ alt success
+ T-->>W: nil
+ W->>App: callback(id) async
+ else failure with retry
+ W->>P: Push(PriorityRetry)
+ else failure or timeout
+ W-->>W: slog error
+ end
+ App->>Q: Shutdown(ctx)
+ Q->>P: Close()
+ Q->>W: wait WaitGroup
+```
+
+## State Machine
+
+```mermaid
+stateDiagram-v2
+ [*] --> Created
+ Created --> Running: Start CAS
+ Running --> Closed: Shutdown CAS
+ Created --> Closed: Shutdown CAS
+ Closed --> Closed: Shutdown idempotent
+```
+
+***
+
+©️ 2025 [邱敬幃 Pardn Chiu](https://www.linkedin.com/in/pardnchiu)
diff --git a/doc/architecture.zh.md b/doc/architecture.zh.md
new file mode 100644
index 0000000..5ee26ef
--- /dev/null
+++ b/doc/architecture.zh.md
@@ -0,0 +1,136 @@
+# go-queue - 架構
+
+> 返回 [README](./README.zh.md)
+
+## 概覽
+
+```mermaid
+graph TB
+ App[應用程式] --> Enqueue[Enqueue]
+ App --> Start[Start]
+ App --> Shutdown[Shutdown]
+ Enqueue --> Pending[待處理 Heap]
+ Start --> Workers[Worker 池]
+ Pending --> Workers
+ Workers --> Execute[執行 / 逾時 / 重試]
+ Shutdown --> Pending
+ Shutdown --> Workers
+```
+
+## Module: Queue
+
+對外 API 與生命週期入口,持有設定、pending 佇列與 worker 協調。
+
+```mermaid
+graph TB
+ subgraph Queue
+ New[New] --> Config[Config / Preset]
+ New --> Pending[pending]
+ Start[Start] --> Workers[worker goroutines]
+ Enqueue[Enqueue] --> Options[EnqueueOption]
+ Enqueue --> Pending
+ Workers --> Execute[execute]
+ Execute --> Retry[setRetry]
+ Retry --> Pending
+ Shutdown[Shutdown] --> Close[pending.Close]
+ Shutdown --> Wait[WaitGroup]
+ end
+ App[呼叫端] --> New
+ App --> Start
+ App --> Enqueue
+ App --> Shutdown
+```
+
+## Module: pending
+
+以 mutex + cond 保護的優先佇列,支援晉升與關閉廣播。
+
+```mermaid
+graph TB
+ subgraph pending
+ Push[Push] --> Heap[taskHeap]
+ Pop[Pop] --> Promote[promoteLocked]
+ Promote --> Heap
+ Pop --> Heap
+ Close[Close] --> Broadcast[cond.Broadcast]
+ Len[Len] --> Heap
+ end
+ Queue[Queue] --> Push
+ Queue --> Pop
+ Queue --> Close
+```
+
+## Module: taskHeap
+
+`container/heap` 實作,依 priority 再依 startAt 排序,並在縮減時回收容量。
+
+```mermaid
+classDiagram
+ class task {
+ +string ID
+ +string preset
+ +Priority priority
+ +func action
+ +Duration timeout
+ +func callback
+ +Time startAt
+ +bool retryOn
+ +int retryMax
+ +int retryTimes
+ }
+ class taskHeap {
+ +taskHeaps tasks
+ +int minCap
+ +Len()
+ +Less()
+ +Swap()
+ +Push()
+ +Pop()
+ }
+ taskHeap --> task : holds
+```
+
+## 資料流
+
+```mermaid
+sequenceDiagram
+ participant App as 應用程式
+ participant Q as Queue
+ participant P as pending
+ participant W as Worker
+ participant T as task action
+
+ App->>Q: New(config)
+ App->>Q: Start(ctx)
+ Q->>W: spawn workers
+ App->>Q: Enqueue(preset, action, opts)
+ Q->>P: Push(task)
+ P-->>W: Pop(task, promotions)
+ W->>T: action(ctx with timeout)
+ alt 成功
+ T-->>W: nil
+ W->>App: callback(id) 非同步
+ else 失敗且可重試
+ W->>P: Push(PriorityRetry)
+ else 失敗或逾時
+ W-->>W: slog error
+ end
+ App->>Q: Shutdown(ctx)
+ Q->>P: Close()
+ Q->>W: wait WaitGroup
+```
+
+## 狀態機
+
+```mermaid
+stateDiagram-v2
+ [*] --> Created
+ Created --> Running: Start CAS
+ Running --> Closed: Shutdown CAS
+ Created --> Closed: Shutdown CAS
+ Closed --> Closed: Shutdown 冪等
+```
+
+***
+
+©️ 2025 [邱敬幃 Pardn Chiu](https://www.linkedin.com/in/pardnchiu)
diff --git a/doc/doc.md b/doc/doc.md
new file mode 100644
index 0000000..efde6f2
--- /dev/null
+++ b/doc/doc.md
@@ -0,0 +1,219 @@
+# go-queue - Documentation
+
+> Back to [README](../README.md)
+
+## Prerequisites
+
+- Go 1.23 or higher
+
+## Installation
+
+### Using go get
+
+```bash
+go get github.com/pardnchiu/go-queue
+```
+
+### From Source
+
+```bash
+git clone https://github.com/pardnchiu/go-queue.git
+cd go-queue
+go test ./...
+```
+
+## Usage
+
+### Basic
+
+```go
+package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+ "time"
+
+ goQueue "github.com/pardnchiu/go-queue/core"
+)
+
+func main() {
+ q := goQueue.New(&goQueue.Config{
+ Workers: 4,
+ })
+
+ ctx := context.Background()
+ if err := q.Start(ctx); err != nil {
+ log.Fatal(err)
+ }
+ defer func() {
+ if err := q.Shutdown(context.Background()); err != nil {
+ log.Printf("shutdown: %v", err)
+ }
+ }()
+
+ id, err := q.Enqueue(ctx, "", func(ctx context.Context) error {
+ fmt.Println("task running")
+ return nil
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println("enqueued:", id)
+ time.Sleep(100 * time.Millisecond)
+}
+```
+
+### Priority Presets
+
+```go
+q := goQueue.New(&goQueue.Config{
+ Workers: 2,
+ Timeout: 30 * time.Second,
+ Preset: map[string]goQueue.PresetConfig{
+ "urgent": {Priority: goQueue.PriorityImmediate},
+ "batch": {Priority: goQueue.PriorityLow, Timeout: 60 * time.Second},
+ },
+})
+
+q.Start(ctx)
+
+// high priority first
+q.Enqueue(ctx, "urgent", func(ctx context.Context) error {
+ // ...
+ return nil
+})
+
+q.Enqueue(ctx, "batch", func(ctx context.Context) error {
+ // ...
+ return nil
+})
+```
+
+### Enqueue Options
+
+```go
+id, err := q.Enqueue(ctx, "urgent", func(ctx context.Context) error {
+ // business logic
+ return nil
+},
+ goQueue.WithTaskID("order-123"),
+ goQueue.WithTimeout(10*time.Second),
+ goQueue.WithRetry(2),
+ goQueue.WithCallback(func(id string) {
+ fmt.Println("done:", id)
+ }),
+)
+if err != nil {
+ log.Fatal(err)
+}
+```
+
+### Graceful Shutdown
+
+```go
+shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+defer cancel()
+
+if err := q.Shutdown(shutdownCtx); err != nil {
+ // timed out: tasks still remaining
+ log.Printf("shutdown: %v", err)
+}
+```
+
+## API Reference
+
+### New
+
+```go
+func New(config *Config) *Queue
+```
+
+Creates a queue. Pass `nil` for defaults.
+
+| Field | Type | Default | Description |
+|------|------|------|------|
+| `Workers` | `int` | `runtime.NumCPU() * 2` | Worker count |
+| `Size` | `int` | `Workers * 64` | Pending queue capacity |
+| `Timeout` | `time.Duration` | `30 * time.Second` | Base timeout |
+| `Preset` | `map[string]PresetConfig` | empty | Named priority/timeout presets |
+
+### PresetConfig
+
+```go
+type PresetConfig struct {
+ Priority Priority
+ Timeout time.Duration
+}
+```
+
+| Field | Description |
+|------|------|
+| `Priority` | Priority level; zero value is `PriorityImmediate` (iota 0) |
+| `Timeout` | When `0`, derived from base `Timeout` by priority |
+
+### Priority
+
+| Constant | Value | Description |
+|------|----|------|
+| `PriorityImmediate` | 0 | Highest, run first |
+| `PriorityHigh` | 1 | High priority |
+| `PriorityRetry` | 2 | Retry tasks |
+| `PriorityNormal` | 3 | Default |
+| `PriorityLow` | 4 | Lowest; may be promoted after wait |
+
+### Start
+
+```go
+func (q *Queue) Start(ctx context.Context) error
+```
+
+Starts the worker pool. Transitions only from `Created` to `Running`; returns error if already started or closed.
+
+### Enqueue
+
+```go
+func (q *Queue) Enqueue(ctx context.Context, presetName string, action func(ctx context.Context) error, options ...EnqueueOption) (string, error)
+```
+
+Enqueues a task and returns its ID. Errors when the queue is closed, full, or `ctx` is canceled.
+
+### EnqueueOption
+
+| Option | Signature | Description |
+|------|------|------|
+| `WithTaskID` | `func WithTaskID(id string) EnqueueOption` | Custom task ID; auto UUID if omitted |
+| `WithTimeout` | `func WithTimeout(d time.Duration) EnqueueOption` | Override per-task timeout |
+| `WithCallback` | `func WithCallback(fn func(id string)) EnqueueOption` | Async callback after success |
+| `WithRetry` | `func WithRetry(retryMax ...int) EnqueueOption` | Enable retries; default max 3 when arg omitted |
+
+### Shutdown
+
+```go
+func (q *Queue) Shutdown(ctx context.Context) error
+```
+
+Closes the queue, drains pending work, and waits for workers. On `ctx` timeout, returns remaining task count. Idempotent.
+
+### Timeout Derivation
+
+Base is `Config.Timeout` (or preset override), then adjusted by priority and clamped to 15s–120s:
+
+| Priority | Formula |
+|----------|------|
+| Immediate | `timeout / 4` |
+| High / Retry | `timeout / 2` |
+| Normal | `timeout` |
+| Low | `timeout * 2` |
+
+### Priority Promotion
+
+| From | Wait | To |
+|------|----------|------|
+| Low | `clamp(Timeout, 30s, 120s)` | Normal |
+| Normal | `clamp(Timeout*2, 30s, 120s)` | High |
+
+***
+
+©️ 2025 [邱敬幃 Pardn Chiu](https://www.linkedin.com/in/pardnchiu)
diff --git a/doc/doc.zh.md b/doc/doc.zh.md
new file mode 100644
index 0000000..b1c60c9
--- /dev/null
+++ b/doc/doc.zh.md
@@ -0,0 +1,219 @@
+# go-queue - 技術文件
+
+> 返回 [README](./README.zh.md)
+
+## 前置需求
+
+- Go 1.23 或更高版本
+
+## 安裝
+
+### 使用 go get
+
+```bash
+go get github.com/pardnchiu/go-queue
+```
+
+### 從原始碼
+
+```bash
+git clone https://github.com/pardnchiu/go-queue.git
+cd go-queue
+go test ./...
+```
+
+## 使用方式
+
+### 基礎用法
+
+```go
+package main
+
+import (
+ "context"
+ "fmt"
+ "log"
+ "time"
+
+ goQueue "github.com/pardnchiu/go-queue/core"
+)
+
+func main() {
+ q := goQueue.New(&goQueue.Config{
+ Workers: 4,
+ })
+
+ ctx := context.Background()
+ if err := q.Start(ctx); err != nil {
+ log.Fatal(err)
+ }
+ defer func() {
+ if err := q.Shutdown(context.Background()); err != nil {
+ log.Printf("shutdown: %v", err)
+ }
+ }()
+
+ id, err := q.Enqueue(ctx, "", func(ctx context.Context) error {
+ fmt.Println("task running")
+ return nil
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println("enqueued:", id)
+ time.Sleep(100 * time.Millisecond)
+}
+```
+
+### 優先級預設
+
+```go
+q := goQueue.New(&goQueue.Config{
+ Workers: 2,
+ Timeout: 30 * time.Second,
+ Preset: map[string]goQueue.PresetConfig{
+ "urgent": {Priority: goQueue.PriorityImmediate},
+ "batch": {Priority: goQueue.PriorityLow, Timeout: 60 * time.Second},
+ },
+})
+
+q.Start(ctx)
+
+// high priority first
+q.Enqueue(ctx, "urgent", func(ctx context.Context) error {
+ // ...
+ return nil
+})
+
+q.Enqueue(ctx, "batch", func(ctx context.Context) error {
+ // ...
+ return nil
+})
+```
+
+### 入隊選項
+
+```go
+id, err := q.Enqueue(ctx, "urgent", func(ctx context.Context) error {
+ // 業務邏輯
+ return nil
+},
+ goQueue.WithTaskID("order-123"),
+ goQueue.WithTimeout(10*time.Second),
+ goQueue.WithRetry(2),
+ goQueue.WithCallback(func(id string) {
+ fmt.Println("done:", id)
+ }),
+)
+if err != nil {
+ log.Fatal(err)
+}
+```
+
+### 優雅關閉
+
+```go
+shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+defer cancel()
+
+if err := q.Shutdown(shutdownCtx); err != nil {
+ // 逾時:仍有任務未完成
+ log.Printf("shutdown: %v", err)
+}
+```
+
+## API 參考
+
+### New
+
+```go
+func New(config *Config) *Queue
+```
+
+建立佇列。`config` 可為 `nil`,此時使用預設值。
+
+| 欄位 | 型別 | 預設 | 說明 |
+|------|------|------|------|
+| `Workers` | `int` | `runtime.NumCPU() * 2` | Worker 數量 |
+| `Size` | `int` | `Workers * 64` | 待處理佇列容量 |
+| `Timeout` | `time.Duration` | `30 * time.Second` | 基準逾時 |
+| `Preset` | `map[string]PresetConfig` | empty | 具名優先級/逾時設定 |
+
+### PresetConfig
+
+```go
+type PresetConfig struct {
+ Priority Priority
+ Timeout time.Duration
+}
+```
+
+| 欄位 | 說明 |
+|------|------|
+| `Priority` | 優先級;零值為 `PriorityImmediate`(iota 0) |
+| `Timeout` | `0` 時依 Priority 由基準 `Timeout` 推算 |
+
+### Priority
+
+| 常數 | 值 | 說明 |
+|------|----|------|
+| `PriorityImmediate` | 0 | 最高,立刻執行 |
+| `PriorityHigh` | 1 | 高優先 |
+| `PriorityRetry` | 2 | 重試任務 |
+| `PriorityNormal` | 3 | 一般 |
+| `PriorityLow` | 4 | 最低;逾時後可晉升 |
+
+### Start
+
+```go
+func (q *Queue) Start(ctx context.Context) error
+```
+
+啟動 worker 池。僅能從 `Created` 轉為 `Running`;重複呼叫或關閉後呼叫會回傳錯誤。
+
+### Enqueue
+
+```go
+func (q *Queue) Enqueue(ctx context.Context, presetName string, action func(ctx context.Context) error, options ...EnqueueOption) (string, error)
+```
+
+將任務入隊並回傳 task ID。佇列已關閉、已滿,或 `ctx` 已取消時回傳錯誤。
+
+### EnqueueOption
+
+| 選項 | 簽章 | 說明 |
+|------|------|------|
+| `WithTaskID` | `func WithTaskID(id string) EnqueueOption` | 自訂 task ID;省略則自動產生 UUID |
+| `WithTimeout` | `func WithTimeout(d time.Duration) EnqueueOption` | 覆寫本次任務逾時 |
+| `WithCallback` | `func WithCallback(fn func(id string)) EnqueueOption` | 成功完成後非同步回呼 |
+| `WithRetry` | `func WithRetry(retryMax ...int) EnqueueOption` | 啟用重試;省略參數時預設最多 3 次 |
+
+### Shutdown
+
+```go
+func (q *Queue) Shutdown(ctx context.Context) error
+```
+
+關閉佇列、排空待處理任務並等待 worker 結束。`ctx` 逾時時回傳剩餘任務數錯誤。可重複呼叫(冪等)。
+
+### 逾時推算規則
+
+基準為 `Config.Timeout`(或 preset 覆寫),再依優先級調整,並限制在 15s–120s:
+
+| Priority | 計算 |
+|----------|------|
+| Immediate | `timeout / 4` |
+| High / Retry | `timeout / 2` |
+| Normal | `timeout` |
+| Low | `timeout * 2` |
+
+### 優先級晉升
+
+| 來源 | 等待時間 | 目標 |
+|------|----------|------|
+| Low | `clamp(Timeout, 30s, 120s)` | Normal |
+| Normal | `clamp(Timeout*2, 30s, 120s)` | High |
+
+***
+
+©️ 2025 [邱敬幃 Pardn Chiu](https://www.linkedin.com/in/pardnchiu)