-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtypes.go
More file actions
164 lines (144 loc) · 5.54 KB
/
types.go
File metadata and controls
164 lines (144 loc) · 5.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package jack
import (
"context"
"errors"
"fmt"
"time"
"github.com/olekukonko/ll"
)
// defaultNumNotifyWorkers specifies the default number of notification workers in the pool.
const defaultNumNotifyWorkers = 100
// retryScheduler specifies the number of retry attempts for submitting tasks when the queue is full.
const (
retryScheduler = 3
retrySchedulerBackoff = time.Millisecond * 100
)
// Errors returned by the worker pool and task execution.
var (
// ErrPoolClosed indicates the worker pool has been closed.
ErrPoolClosed = errors.New("pool has been closed")
// ErrRunnerClosed indicates the runner has been closed.
ErrRunnerClosed = errors.New("runner has been closed")
// ErrSchedulerClosed indicates the scheduler has been closed.
ErrSchedulerClosed = errors.New("scheduler has been closed")
// ErrTaskTimeout indicates a task exceeded its execution timeout.
ErrTaskTimeout = errors.New("task execution timed out")
// ErrTaskPanic indicates a task panicked during execution.
ErrTaskPanic = errors.New("task panicked during execution")
// ErrQueueFull indicates the task queue is full and cannot accept new tasks.
ErrQueueFull = errors.New("task queue is full")
// ErrShutdownTimedOut indicates the pool shutdown exceeded its timeout.
ErrShutdownTimedOut = errors.New("shutdown timed out")
)
var (
ErrSchedulerJobAlreadyRunning = errors.New("scheduler: job is already running")
ErrSchedulerNotRunning = errors.New("scheduler: job is not running or already stopped")
ErrSchedulerPoolNil = errors.New("scheduler: pool cannot be nil")
ErrSchedulerNameMissing = errors.New("scheduler: name cannot be empty")
)
// logger is the default logger for the jack package, initialized with the "jack" namespace.
var logger = ll.New("jack").Disable()
// Identifiable is an optional interface for tasks to provide a custom ID for logging, metrics, and tracing.
type Identifiable interface {
// ID returns a unique identifier for the task.
ID() string
}
// job defines a task that can be executed by a worker in the pool.
// It includes methods for execution, identification, and context retrieval.
type job interface {
// Run executes the task with the given context and returns any error.
Run(ctx context.Context) error
// ID returns a unique identifier for the task.
ID() string
// Context returns the task's associated context.
Context() context.Context
}
// Task represents a simple task that can be executed without a context.
type Task interface {
// Do executes the task and returns any error.
Do() error
}
// TaskCtx represents a context-aware task that can be executed with a context.
type TaskCtx interface {
// Do executes the task with the given context and returns any error.
Do(ctx context.Context) error
}
// Event captures details of task execution for observability.
// Thread-safe for use in notification across goroutines.
type Event struct {
Type string // Type of event: "queued", "run", "done"
TaskID string // Optional task identifier
WorkerID string // Identifier of the worker processing the task
Time time.Time // Time of the event
Duration time.Duration // Duration of task execution (for "done" events)
Err error // Error, if any (for "done" events)
}
// Logger returns the default logger for the jack package.
// Thread-safe as it returns a pre-initialized logger.
// Example:
//
// log := jack.Logger() // Retrieves the default logger
func Logger() *ll.Logger {
return logger
}
// Routine configures recurring task execution with an interval and maximum runs.
// Thread-safe for use in scheduling configurations.
type Routine struct {
Interval time.Duration // Interval between task executions
MaxRuns int // Maximum number of runs (0 for unlimited)
Cron string // Cron expression (e.g., "0 0 * * *" for daily at midnight, "@every 1m")
}
// Package jack provides utilities for safe, context-aware function execution with mutex protection.
// It includes methods to execute functions with panic recovery, context cancellation support,
// and mutex locking, eliminating the need for verbose boilerplate when handling timeouts or cancellations.
// CaughtPanic represents a panic that was caught during execution.
type CaughtPanic struct {
Value interface{} // The value passed to panic()
Stack []byte // The stack trace (may be empty if not collected)
}
// Error implements the error interface.
func (c *CaughtPanic) Error() string {
if c.Stack != nil {
return fmt.Sprintf("panic: %v\nstack:\n%s", c.Value, c.Stack)
}
return fmt.Sprintf("panic: %v", c.Value)
}
// String provides a formatted string representation of the panic.
func (c *CaughtPanic) String() string {
return c.Error()
}
// Unwrap provides compatibility with errors.Is/As.
func (c *CaughtPanic) Unwrap() error {
if err, ok := c.Value.(error); ok {
return err
}
return nil
}
// Do wraps a function with no return value into a Task.
// Useful for fire-and-forget or simple operations that don’t produce errors.
//
// Example:
//
// pool.Submit(jack.Do(func() {
// fmt.Println("Hello from task")
// }))
func Do(fn func()) Task {
return Func(func() error {
fn()
return nil
})
}
// DoCtx wraps a context-aware function with no return value into a TaskCtx.
// Useful when you only need context propagation without returning an error.
//
// Example:
//
// pool.SubmitCtx(ctx, jack.DoCtx(func(ctx context.Context) {
// fmt.Println("Running with context:", ctx)
// }))
func DoCtx(fn func(ctx context.Context)) TaskCtx {
return FuncCtx(func(ctx context.Context) error {
fn(ctx)
return nil
})
}