modelRT/task/handler_factory.go

247 lines
6.9 KiB
Go

// Package task provides asynchronous task processing with handler factory pattern
package task
import (
"context"
"fmt"
"sync"
"modelRT/logger"
"github.com/gofrs/uuid"
"gorm.io/gorm"
)
// TaskHandler defines the interface for task processors
type TaskHandler interface {
// Execute processes a task with the given ID and type
Execute(ctx context.Context, taskID uuid.UUID, taskType TaskType, db *gorm.DB) error
// CanHandle returns true if this handler can process the given task type
CanHandle(taskType TaskType) bool
// Name returns the name of the handler for logging and metrics
Name() string
}
// HandlerFactory creates task handlers based on task type
type HandlerFactory struct {
handlers map[TaskType]TaskHandler
mu sync.RWMutex
}
// NewHandlerFactory creates a new HandlerFactory
func NewHandlerFactory() *HandlerFactory {
return &HandlerFactory{
handlers: make(map[TaskType]TaskHandler),
}
}
// RegisterHandler registers a handler for a specific task type
func (f *HandlerFactory) RegisterHandler(taskType TaskType, handler TaskHandler) {
f.mu.Lock()
defer f.mu.Unlock()
f.handlers[taskType] = handler
logger.Info(context.Background(), "Handler registered",
"task_type", taskType,
"handler_name", handler.Name(),
)
}
// GetHandler returns a handler for the given task type
func (f *HandlerFactory) GetHandler(taskType TaskType) (TaskHandler, error) {
f.mu.RLock()
handler, exists := f.handlers[taskType]
f.mu.RUnlock()
if !exists {
return nil, fmt.Errorf("no handler registered for task type: %s", taskType)
}
return handler, nil
}
// CreateDefaultHandlers registers all default task handlers
func (f *HandlerFactory) CreateDefaultHandlers() {
f.RegisterHandler(TypeTopologyAnalysis, &TopologyAnalysisHandler{})
f.RegisterHandler(TypeEventAnalysis, &EventAnalysisHandler{})
f.RegisterHandler(TypeBatchImport, &BatchImportHandler{})
}
// BaseHandler provides common functionality for all task handlers
type BaseHandler struct {
name string
}
// NewBaseHandler creates a new BaseHandler
func NewBaseHandler(name string) *BaseHandler {
return &BaseHandler{name: name}
}
// Name returns the handler name
func (h *BaseHandler) Name() string {
return h.name
}
// TopologyAnalysisHandler handles topology analysis tasks
type TopologyAnalysisHandler struct {
BaseHandler
}
// NewTopologyAnalysisHandler creates a new TopologyAnalysisHandler
func NewTopologyAnalysisHandler() *TopologyAnalysisHandler {
return &TopologyAnalysisHandler{
BaseHandler: *NewBaseHandler("topology_analysis_handler"),
}
}
// Execute processes a topology analysis task
func (h *TopologyAnalysisHandler) Execute(ctx context.Context, taskID uuid.UUID, taskType TaskType, db *gorm.DB) error {
logger.Info(ctx, "Starting topology analysis",
"task_id", taskID,
"task_type", taskType,
)
// TODO: Implement actual topology analysis logic
// This would typically involve:
// 1. Fetching task parameters from database
// 2. Performing topology analysis (checking for islands, shorts, etc.)
// 3. Storing results in database
// 4. Updating task status
// Simulate work
logger.Info(ctx, "Topology analysis completed",
"task_id", taskID,
"task_type", taskType,
)
return nil
}
// CanHandle returns true for topology analysis tasks
func (h *TopologyAnalysisHandler) CanHandle(taskType TaskType) bool {
return taskType == TypeTopologyAnalysis
}
// EventAnalysisHandler handles event analysis tasks
type EventAnalysisHandler struct {
BaseHandler
}
// NewEventAnalysisHandler creates a new EventAnalysisHandler
func NewEventAnalysisHandler() *EventAnalysisHandler {
return &EventAnalysisHandler{
BaseHandler: *NewBaseHandler("event_analysis_handler"),
}
}
// Execute processes an event analysis task
func (h *EventAnalysisHandler) Execute(ctx context.Context, taskID uuid.UUID, taskType TaskType, db *gorm.DB) error {
logger.Info(ctx, "Starting event analysis",
"task_id", taskID,
"task_type", taskType,
)
// TODO: Implement actual event analysis logic
// This would typically involve:
// 1. Fetching motor and trigger information
// 2. Analyzing events within the specified duration
// 3. Generating analysis report
// 4. Storing results in database
// Simulate work
logger.Info(ctx, "Event analysis completed",
"task_id", taskID,
"task_type", taskType,
)
return nil
}
// CanHandle returns true for event analysis tasks
func (h *EventAnalysisHandler) CanHandle(taskType TaskType) bool {
return taskType == TypeEventAnalysis
}
// BatchImportHandler handles batch import tasks
type BatchImportHandler struct {
BaseHandler
}
// NewBatchImportHandler creates a new BatchImportHandler
func NewBatchImportHandler() *BatchImportHandler {
return &BatchImportHandler{
BaseHandler: *NewBaseHandler("batch_import_handler"),
}
}
// Execute processes a batch import task
func (h *BatchImportHandler) Execute(ctx context.Context, taskID uuid.UUID, taskType TaskType, db *gorm.DB) error {
logger.Info(ctx, "Starting batch import",
"task_id", taskID,
"task_type", taskType,
)
// TODO: Implement actual batch import logic
// This would typically involve:
// 1. Reading file from specified path
// 2. Parsing file content (CSV, Excel, etc.)
// 3. Validating and importing data into database
// 4. Generating import report
// Simulate work
logger.Info(ctx, "Batch import completed",
"task_id", taskID,
"task_type", taskType,
)
return nil
}
// CanHandle returns true for batch import tasks
func (h *BatchImportHandler) CanHandle(taskType TaskType) bool {
return taskType == TypeBatchImport
}
// CompositeHandler can handle multiple task types by delegating to appropriate handlers
type CompositeHandler struct {
factory *HandlerFactory
}
// NewCompositeHandler creates a new CompositeHandler
func NewCompositeHandler(factory *HandlerFactory) *CompositeHandler {
return &CompositeHandler{factory: factory}
}
// Execute delegates task execution to the appropriate handler
func (h *CompositeHandler) Execute(ctx context.Context, taskID uuid.UUID, taskType TaskType, db *gorm.DB) error {
handler, err := h.factory.GetHandler(taskType)
if err != nil {
return fmt.Errorf("failed to get handler for task type %s: %w", taskType, err)
}
return handler.Execute(ctx, taskID, taskType, db)
}
// CanHandle returns true if any registered handler can handle the task type
func (h *CompositeHandler) CanHandle(taskType TaskType) bool {
_, err := h.factory.GetHandler(taskType)
return err == nil
}
// Name returns the composite handler name
func (h *CompositeHandler) Name() string {
return "composite_handler"
}
// DefaultHandlerFactory returns a HandlerFactory with all default handlers registered
func DefaultHandlerFactory() *HandlerFactory {
factory := NewHandlerFactory()
factory.CreateDefaultHandlers()
return factory
}
// DefaultCompositeHandler returns a CompositeHandler with all default handlers
func DefaultCompositeHandler() TaskHandler {
factory := DefaultHandlerFactory()
return NewCompositeHandler(factory)
}