Add Jobs API for background task management
- Add JobsHandler with CreateJob and GetJobStatus endpoints - Add jobs router with POST /api/jobs and GET /api/jobs/:jobId routes - Integrate JobsHandler into main server and router config
This commit is contained in:
@@ -106,6 +106,7 @@ func main() {
|
||||
|
||||
// Create worker for background tasks
|
||||
worker := services.NewWorker(3)
|
||||
services.WorkerInstance = worker
|
||||
|
||||
koreaderHandler := handlers.NewKOReaderHandler(queries, connManager, queueProcessor)
|
||||
wsHandler := handlers.NewWSHandler(queries, connManager, cfg.JWTSecret, deviceAuthMiddleware)
|
||||
@@ -123,6 +124,7 @@ func main() {
|
||||
dashboardHandler := handlers.NewDashboardHandler(queries)
|
||||
mediaHandler := handlers.NewMediaHandler(queries, libraryService, worker)
|
||||
matchingHandler := handlers.NewMatchingHandler(queries, connManager)
|
||||
jobsHandler := handlers.NewJobsHandler(queries, worker)
|
||||
|
||||
e := echo.New()
|
||||
|
||||
@@ -177,6 +179,7 @@ func main() {
|
||||
ConnManager: connManager,
|
||||
QueueProcessor: queueProcessor,
|
||||
DeviceAuthMiddleware: deviceAuthMiddleware,
|
||||
JobsHandler: jobsHandler,
|
||||
LoginTracker: loginAttemptTracker,
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"bookhoard/internal/database"
|
||||
"bookhoard/internal/services"
|
||||
)
|
||||
|
||||
type JobsHandler struct {
|
||||
db *database.Queries
|
||||
worker *services.Worker
|
||||
}
|
||||
|
||||
func NewJobsHandler(db *database.Queries, worker *services.Worker) *JobsHandler {
|
||||
return &JobsHandler{
|
||||
db: db,
|
||||
worker: worker,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateJob creates a new job based on type
|
||||
func (h *JobsHandler) CreateJob(c echo.Context) error {
|
||||
var req struct {
|
||||
Type string `json:"type"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
}
|
||||
|
||||
if err := c.Bind(&req); err != nil {
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{
|
||||
"error": "Invalid request body",
|
||||
})
|
||||
}
|
||||
|
||||
// Validate job type
|
||||
var jobType services.JobType
|
||||
switch req.Type {
|
||||
case "import", "convert", "thumbnails", "backup", "analytics", "sync":
|
||||
jobType = services.JobType(req.Type)
|
||||
default:
|
||||
return c.JSON(http.StatusBadRequest, map[string]string{
|
||||
"error": "Invalid job type",
|
||||
})
|
||||
}
|
||||
|
||||
// Add database to params
|
||||
req.Params["db"] = h.db
|
||||
|
||||
// Create job
|
||||
job := &services.Job{
|
||||
ID: uuid.New().String(),
|
||||
Type: jobType,
|
||||
Params: req.Params,
|
||||
Status: services.JobStatusPending,
|
||||
}
|
||||
|
||||
// Enqueue job
|
||||
if err := h.worker.EnqueueJob(job); err != nil {
|
||||
return c.JSON(http.StatusInternalServerError, map[string]string{
|
||||
"error": "Failed to enqueue job",
|
||||
})
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusAccepted, map[string]interface{}{
|
||||
"message": "Job created",
|
||||
"job_id": job.ID,
|
||||
"type": req.Type,
|
||||
"status": "pending",
|
||||
})
|
||||
}
|
||||
|
||||
// GetJobStatus returns the status of a specific job
|
||||
func (h *JobsHandler) GetJobStatus(c echo.Context) error {
|
||||
jobID := c.Param("jobId")
|
||||
|
||||
result, exists := h.worker.GetJobStatus(jobID)
|
||||
if !exists {
|
||||
return c.JSON(http.StatusNotFound, map[string]string{
|
||||
"error": "Job not found",
|
||||
})
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, result)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package router
|
||||
|
||||
func registerJobRoutes(cfg *Config) {
|
||||
e := cfg.Echo
|
||||
jwtMiddleware := createJWTMiddleware(cfg)
|
||||
protected := e.Group("/api", jwtMiddleware)
|
||||
jobs := protected.Group("/jobs")
|
||||
jobs.POST("", cfg.JobsHandler.CreateJob)
|
||||
jobs.GET("/:jobId", cfg.JobsHandler.GetJobStatus)
|
||||
}
|
||||
@@ -61,6 +61,7 @@ type Config struct {
|
||||
DeviceAuthMiddleware *middleware.DeviceAuthMiddleware
|
||||
LoginTracker *ratelimit.LoginAttemptTracker
|
||||
ScannerHandler *handlers.Handler
|
||||
JobsHandler *handlers.JobsHandler
|
||||
}
|
||||
|
||||
// createJWTMiddleware creates a JWT middleware with proper user context setup
|
||||
@@ -217,6 +218,7 @@ func RegisterRoutes(cfg *Config) *handlers.Handler {
|
||||
registerConflictRoutes(cfg)
|
||||
registerAnalyticsRoutes(cfg)
|
||||
registerQueueRoutes(cfg)
|
||||
registerJobRoutes(cfg)
|
||||
registerOPDSRoutes(cfg)
|
||||
registerWebSocketRoutes(cfg)
|
||||
registerFrontendRoutes(cfg)
|
||||
|
||||
Reference in New Issue
Block a user