170 lines
4.5 KiB
Go
170 lines
4.5 KiB
Go
|
|
// Package task provides test task implementation for system verification
|
||
|
|
package task
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"fmt"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"modelRT/database"
|
||
|
|
"modelRT/logger"
|
||
|
|
"modelRT/orm"
|
||
|
|
|
||
|
|
"github.com/gofrs/uuid"
|
||
|
|
"gorm.io/gorm"
|
||
|
|
)
|
||
|
|
|
||
|
|
// TestTaskParams defines parameters for test task
|
||
|
|
type TestTaskParams struct {
|
||
|
|
// SleepDuration specifies how long the task should sleep (in seconds)
|
||
|
|
// Default is 60 seconds as per requirement
|
||
|
|
SleepDuration int `json:"sleep_duration"`
|
||
|
|
// Message is a custom message to include in the result
|
||
|
|
Message string `json:"message,omitempty"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate checks if test task parameters are valid
|
||
|
|
func (p *TestTaskParams) Validate() error {
|
||
|
|
// Default to 60 seconds if not specified
|
||
|
|
if p.SleepDuration <= 0 {
|
||
|
|
p.SleepDuration = 60
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate max duration (max 1 hour)
|
||
|
|
if p.SleepDuration > 3600 {
|
||
|
|
return fmt.Errorf("sleep duration cannot exceed 3600 seconds (1 hour)")
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetType returns the task type
|
||
|
|
func (p *TestTaskParams) GetType() UnifiedTaskType {
|
||
|
|
return TaskTypeTest
|
||
|
|
}
|
||
|
|
|
||
|
|
// ToMap converts parameters to map for database storage
|
||
|
|
func (p *TestTaskParams) ToMap() map[string]interface{} {
|
||
|
|
return map[string]interface{}{
|
||
|
|
"sleep_duration": p.SleepDuration,
|
||
|
|
"message": p.Message,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// FromMap populates parameters from map (for database retrieval)
|
||
|
|
func (p *TestTaskParams) FromMap(params map[string]interface{}) error {
|
||
|
|
if v, ok := params["sleep_duration"]; ok {
|
||
|
|
if duration, isFloat := v.(float64); isFloat {
|
||
|
|
p.SleepDuration = int(duration)
|
||
|
|
} else if duration, isInt := v.(int); isInt {
|
||
|
|
p.SleepDuration = duration
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if v, ok := params["message"]; ok {
|
||
|
|
if msg, isString := v.(string); isString {
|
||
|
|
p.Message = msg
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// TestTask implements a test task that sleeps for specified duration
|
||
|
|
// This task contains no I/O operations as per requirements
|
||
|
|
type TestTask struct {
|
||
|
|
*BaseTask
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewTestTask creates a new TestTask instance
|
||
|
|
func NewTestTask(params TestTaskParams) *TestTask {
|
||
|
|
return &TestTask{
|
||
|
|
BaseTask: NewBaseTask(TaskTypeTest, ¶ms, "test_task"),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Execute performs the test task logic (sleep without I/O operations)
|
||
|
|
func (t *TestTask) Execute(ctx context.Context, taskID uuid.UUID, db *gorm.DB) error {
|
||
|
|
params, ok := t.GetParams().(*TestTaskParams)
|
||
|
|
if !ok {
|
||
|
|
return fmt.Errorf("invalid parameter type for TestTask")
|
||
|
|
}
|
||
|
|
|
||
|
|
logger.Info(ctx, "Starting test task execution",
|
||
|
|
"task_id", taskID,
|
||
|
|
"sleep_duration_seconds", params.SleepDuration,
|
||
|
|
"message", params.Message,
|
||
|
|
)
|
||
|
|
|
||
|
|
// Sleep for the specified duration without any I/O operations
|
||
|
|
// This is pure CPU-time wait as per requirements
|
||
|
|
sleepDuration := time.Duration(params.SleepDuration) * time.Second
|
||
|
|
time.Sleep(sleepDuration)
|
||
|
|
|
||
|
|
// Build result
|
||
|
|
result := map[string]interface{}{
|
||
|
|
"status": "completed",
|
||
|
|
"sleep_duration": params.SleepDuration,
|
||
|
|
"message": params.Message,
|
||
|
|
"executed_at": time.Now().Unix(),
|
||
|
|
"task_id": taskID.String(),
|
||
|
|
}
|
||
|
|
|
||
|
|
// Save result to database
|
||
|
|
if err := database.UpdateAsyncTaskResultWithSuccess(ctx, db, taskID, orm.JSONMap(result)); err != nil {
|
||
|
|
logger.Error(ctx, "Failed to save test task result",
|
||
|
|
"task_id", taskID,
|
||
|
|
"error", err,
|
||
|
|
)
|
||
|
|
return fmt.Errorf("failed to save task result: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
logger.Info(ctx, "Test task completed successfully",
|
||
|
|
"task_id", taskID,
|
||
|
|
"sleep_duration_seconds", params.SleepDuration,
|
||
|
|
)
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// TestTaskHandler handles test task execution
|
||
|
|
type TestTaskHandler struct {
|
||
|
|
*BaseHandler
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewTestTaskHandler creates a new TestTaskHandler
|
||
|
|
func NewTestTaskHandler() *TestTaskHandler {
|
||
|
|
return &TestTaskHandler{
|
||
|
|
BaseHandler: NewBaseHandler("test_task_handler"),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Execute processes a test task using the unified task interface
|
||
|
|
func (h *TestTaskHandler) Execute(ctx context.Context, taskID uuid.UUID, taskType TaskType, db *gorm.DB) error {
|
||
|
|
logger.Info(ctx, "Executing test task",
|
||
|
|
"task_id", taskID,
|
||
|
|
"task_type", taskType,
|
||
|
|
)
|
||
|
|
|
||
|
|
// Fetch task parameters from database
|
||
|
|
asyncTask, err := database.GetAsyncTaskByID(ctx, db, taskID)
|
||
|
|
if err != nil {
|
||
|
|
return fmt.Errorf("failed to fetch task: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Convert params map to TestTaskParams
|
||
|
|
params := &TestTaskParams{}
|
||
|
|
if err := params.FromMap(map[string]interface{}(asyncTask.Params)); err != nil {
|
||
|
|
return fmt.Errorf("failed to parse task params: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Create and execute test task
|
||
|
|
testTask := NewTestTask(*params)
|
||
|
|
return testTask.Execute(ctx, taskID, db)
|
||
|
|
}
|
||
|
|
|
||
|
|
// CanHandle returns true for test tasks
|
||
|
|
func (h *TestTaskHandler) CanHandle(taskType TaskType) bool {
|
||
|
|
return string(TaskTypeTest) == string(taskType)
|
||
|
|
}
|