Appearance
Integration
Environment Requirements
Go 1.24.3 or higher is required for building and running applications using tasker
. The library is platform-agnostic and should run on any operating system supported by Go.
Initialization Patterns
The most common way to initialize tasker
is by providing OnCreate
, OnDestroy
, WorkerCount
, and a context.Context
.
go
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/asaidimu/tasker/v2"
)
// MyResource represents a resource for tasks
type MyResource struct{ ID int }
// onCreate simulates resource allocation
func createMyResource() (*MyResource, error) {
fmt.Println("INFO: Creating MyResource")
return &MyResource{ID: time.Now().Nanosecond()}, nil
}
// onDestroy simulates resource deallocation
func destroyMyResource(r *MyResource) error {
fmt.Println("INFO: Destroying MyResource", r.ID)
return nil
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
config := tasker.Config[*MyResource]{
OnCreate: createMyResource,
OnDestroy: destroyMyResource,
WorkerCount: 2, // Two base workers
Ctx: ctx,
}
manager, err := tasker.NewTaskManager[*MyResource, string](config)
if err != nil {
log.Fatalf("Error creating task manager: %v", err)
}
defer manager.Stop()
fmt.Println("TaskManager initialized and running.")
// Application logic here
time.Sleep(500 * time.Millisecond)
}
Integrate custom logging and metrics collection by implementing the tasker.Logger
and tasker.MetricsCollector
interfaces.
go
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/asaidimu/tasker/v2"
)
// MyCustomLogger implements tasker.Logger
type MyCustomLogger struct{}
func (l *MyCustomLogger) Debugf(format string, args ...any) { log.Printf("[DEBUG] "+format, args...) }
func (l *MyCustomLogger) Infof(format string, args ...any) { log.Printf("[INFO] "+format, args...) }
func (l *MyCustomLogger) Warnf(format string, args ...any) { log.Printf("[WARN] "+format, args...) }
func (l *MyCustomLogger) Errorf(format string, args ...any) { log.Printf("[ERROR] "+format, args...) }
// MyCustomMetricsCollector implements tasker.MetricsCollector
type MyCustomMetricsCollector struct{}
func (c *MyCustomMetricsCollector) RecordArrival() { fmt.Println("Metric: Task Arrived") }
func (c *MyCustomMetricsCollector) RecordCompletion(s tasker.TaskLifecycleTimestamps) { fmt.Printf("Metric: Task Completed (exec: %v)\n", s.FinishedAt.Sub(s.StartedAt)) }
func (c *MyCustomMetricsCollector) RecordFailure(s tasker.TaskLifecycleTimestamps) { fmt.Println("Metric: Task Failed") }
func (c *MyCustomMetricsCollector) RecordRetry() { fmt.Println("Metric: Task Retried") }
func (c *MyCustomMetricsCollector) Metrics() tasker.TaskMetrics { return tasker.TaskMetrics{} }
// MyResource and lifecycle functions (same as above)
type MyResource struct{ ID int }
func createMyResource() (*MyResource, error) { fmt.Println("INFO: Creating MyResource"); return &MyResource{ID: time.Now().Nanosecond()}, nil }
func destroyMyResource(r *MyResource) error { fmt.Println("INFO: Destroying MyResource", r.ID); return nil }
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
config := tasker.Config[*MyResource]{
OnCreate: createMyResource,
OnDestroy: destroyMyResource,
WorkerCount: 1,
Ctx: ctx,
Logger: &MyCustomLogger{}, // Provide custom logger
Collector: &MyCustomMetricsCollector{}, // Provide custom collector
}
manager, err := tasker.NewTaskManager[*MyResource, string](config)
if err != nil {
log.Fatalf("Error creating task manager: %v", err)
}
defer manager.Stop()
_, _ = manager.QueueTask(func(ctx context.Context, res *MyResource) (string, error) {
fmt.Printf("Worker %d processing a task with custom logging/metrics\n", res.ID)
return "done", nil
})
time.Sleep(100 * time.Millisecond)
}
Common Pitfalls
Not handling context.Context
cancellation within task functions.
Solution: Tasks should periodically check ctx.Done()
or use select { case <-ctx.Done(): return nil, ctx.Err() ... }
to respond to manager shutdowns or timeouts.
Blocking indefinitely in OnCreate
, OnDestroy
, or task functions.
Solution: Ensure these functions complete in a timely manner. Long-running initialization/cleanup should be handled asynchronously or outside tasker
's direct control if it risks blocking the pool.
Ignoring errors returned by QueueTask
or RunTask
.
Solution: Always check the error
return value to handle potential submission failures (e.g., manager shutting down) or task execution errors.
Lifecycle Dependencies
The TaskManager
relies on a parent context.Context
for its overall lifecycle. Cancelling this context (passed via Config.Ctx
) initiates a graceful shutdown (Stop()
behavior). Users must ensure the TaskManager
's Stop()
or Kill()
method is called when the application exits to properly release resources and wait for tasks (for Stop()
). Resource creation (OnCreate
) and destruction (OnDestroy
) are directly tied to worker lifecycles and the RunTask
operation. Workers will not start if OnCreate
fails, and resources are destroyed when workers exit or the manager shuts down.