/
AngelCareMe
/
task_queue
Обзор
Документация
Войти
/
AngelCareMe
/
task_queue
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
internal/handler/task/task_handler.go
244 строки
7 KB
AngelCareMe
done
28 июл 2025, 21:07
28 июл 2025, 21:07
c70014b
Код
Авторство
О чём код?
package task import ( "net/http" "strconv" "task-queue/internal/entity" "task-queue/internal/service" "task-queue/pkg/logger" "task-queue/pkg/validator" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" ) type handler struct { taskService service.TaskService logger *logrus.Logger } func NewHandler(taskService service.TaskService) Handler { return &handler{ taskService: taskService, logger: logger.Get(), } } // createTask creates new task // @Summary Create new task // @Description Create new task and put it to queue // @Tags tasks // @Accept json // @Produce json // @Param task body CreateRequest true "Task creation request" // @Success 201 {object} entity.Task // @Failure 400 {object} ErrorResponse // @Failure 500 {object} ErrorResponse // @Router /tasks [post] func (h *handler) CreateTask(c *gin.Context) { var req CreateRequest if err := c.ShouldBindJSON(&req); err != nil { h.logger.WithError(err).Error("failed to bind task create request") c.JSON(http.StatusBadRequest, ErrorResponse{Error: "invalid request format"}) return } // validate request if err := validator.ValidateStruct(req); err != nil { if validator.IsValidationError(err) { c.JSON(http.StatusBadRequest, ErrorResponse{Error: err.Error()}) return } h.logger.WithError(err).Error("validation error") c.JSON(http.StatusBadRequest, ErrorResponse{Error: "validation failed"}) return } serviceReq := &service.TaskCreateRequest{ Name: req.Name, Payload: req.Payload, MaxRetry: req.MaxRetry, Delay: req.Delay, } task, err := h.taskService.CreateTask(c.Request.Context(), serviceReq) if err != nil { h.logger.WithError(err).Error("failed to create task through service") c.JSON(http.StatusInternalServerError, ErrorResponse{Error: "failed to create task"}) return } c.JSON(http.StatusCreated, task) } // getTask gets task by id // @Summary Get task by ID // @Description Get task details by ID // @Tags tasks // @Accept json // @Produce json // @Param id path string true "Task ID" // @Success 200 {object} entity.Task // @Failure 400 {object} ErrorResponse // @Failure 404 {object} ErrorResponse // @Failure 500 {object} ErrorResponse // @Router /tasks/{id} [get] func (h *handler) GetTask(c *gin.Context) { id := c.Param("id") if id == "" { c.JSON(http.StatusBadRequest, ErrorResponse{Error: "task id is required"}) return } task, err := h.taskService.GetTask(c.Request.Context(), id) if err != nil { h.logger.WithError(err).WithField("task_id", id).Error("failed to get task") c.JSON(http.StatusNotFound, ErrorResponse{Error: "task not found"}) return } c.JSON(http.StatusOK, task) } // listTasks lists tasks with filtering // @Summary List tasks // @Description List tasks with optional filtering and pagination // @Tags tasks // @Accept json // @Produce json // @Param status query string false "Filter by status" // @Param name query string false "Filter by name" // @Param limit query int false "Limit results" default(10) // @Param offset query int false "Offset results" default(0) // @Success 200 {object} service.TaskListResponse // @Failure 400 {object} ErrorResponse // @Failure 500 {object} ErrorResponse // @Router /tasks [get] func (h *handler) ListTasks(c *gin.Context) { var query ListQuery if err := c.ShouldBindQuery(&query); err != nil { h.logger.WithError(err).Error("failed to bind task list query") c.JSON(http.StatusBadRequest, ErrorResponse{Error: "invalid query parameters"}) return } // parse query parameters var status *entity.TaskStatus if query.Status != "" { taskStatus := entity.TaskStatus(query.Status) status = &taskStatus } var name *string if query.Name != "" { name = &query.Name } limit := 10 if query.Limit != "" { if parsedLimit, err := strconv.Atoi(query.Limit); err == nil && parsedLimit > 0 { limit = parsedLimit } } offset := 0 if query.Offset != "" { if parsedOffset, err := strconv.Atoi(query.Offset); err == nil && parsedOffset >= 0 { offset = parsedOffset } } serviceReq := &service.TaskListRequest{ Status: status, Name: name, Limit: limit, Offset: offset, } response, err := h.taskService.ListTasks(c.Request.Context(), serviceReq) if err != nil { h.logger.WithError(err).Error("failed to list tasks through service") c.JSON(http.StatusInternalServerError, ErrorResponse{Error: "failed to list tasks"}) return } c.JSON(http.StatusOK, response) } // retryTask retries task // @Summary Retry task // @Description Put task back to queue for reprocessing // @Tags tasks // @Accept json // @Produce json // @Param id path string true "Task ID" // @Success 200 {object} MessageResponse // @Failure 400 {object} ErrorResponse // @Failure 404 {object} ErrorResponse // @Failure 500 {object} ErrorResponse // @Router /tasks/{id}/retry [post] func (h *handler) RetryTask(c *gin.Context) { id := c.Param("id") if id == "" { c.JSON(http.StatusBadRequest, ErrorResponse{Error: "task id is required"}) return } err := h.taskService.RetryTask(c.Request.Context(), id) if err != nil { h.logger.WithError(err).WithField("task_id", id).Error("failed to retry task") c.JSON(http.StatusInternalServerError, ErrorResponse{Error: "failed to retry task"}) return } c.JSON(http.StatusOK, MessageResponse{Message: "task scheduled for retry"}) } // deleteTask deletes task // @Summary Delete task // @Description Delete task by ID // @Tags tasks // @Accept json // @Produce json // @Param id path string true "Task ID" // @Success 200 {object} MessageResponse // @Failure 400 {object} ErrorResponse // @Failure 404 {object} ErrorResponse // @Failure 500 {object} ErrorResponse // @Router /tasks/{id} [delete] func (h *handler) DeleteTask(c *gin.Context) { id := c.Param("id") if id == "" { c.JSON(http.StatusBadRequest, ErrorResponse{Error: "task id is required"}) return } err := h.taskService.DeleteTask(c.Request.Context(), id) if err != nil { h.logger.WithError(err).WithField("task_id", id).Error("failed to delete task") c.JSON(http.StatusInternalServerError, ErrorResponse{Error: "failed to delete task"}) return } c.JSON(http.StatusOK, MessageResponse{Message: "task deleted successfully"}) } // getTaskStats gets task statistics // @Summary Get task statistics // @Description Get statistics about all tasks // @Tags tasks // @Accept json // @Produce json // @Success 200 {object} service.TaskStatsResponse // @Failure 500 {object} ErrorResponse // @Router /tasks/stats [get] func (h *handler) GetTaskStats(c *gin.Context) { stats, err := h.taskService.GetTaskStats(c.Request.Context()) if err != nil { h.logger.WithError(err).Error("failed to get task stats through service") c.JSON(http.StatusInternalServerError, ErrorResponse{Error: "failed to get task stats"}) return } c.JSON(http.StatusOK, stats) }