188 lines
5.6 KiB
Go
188 lines
5.6 KiB
Go
package pages
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"git.ourworld.tf/herocode/heroagent/pkg/herojobs"
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
// JobDisplayInfo represents information about a job for display purposes
|
|
type JobDisplayInfo struct {
|
|
JobID string `json:"jobid"`
|
|
CircleID string `json:"circleid"`
|
|
Topic string `json:"topic"`
|
|
Status string `json:"status"`
|
|
SessionKey string `json:"sessionkey"`
|
|
Params string `json:"params"`
|
|
ParamsType string `json:"paramstype"`
|
|
Result string `json:"result"`
|
|
Error string `json:"error"`
|
|
TimeScheduled int64 `json:"time_scheduled"`
|
|
TimeStart int64 `json:"time_start"`
|
|
TimeEnd int64 `json:"time_end"`
|
|
Timeout int64 `json:"timeout"`
|
|
}
|
|
|
|
// JobHandler handles job-related page routes
|
|
type JobHandler struct {
|
|
client *herojobs.RedisClient
|
|
logger *log.Logger
|
|
}
|
|
|
|
// NewJobHandler creates a new job handler with the provided socket path
|
|
func NewJobHandler(redisAddr string, logger *log.Logger) (*JobHandler, error) {
|
|
// Assuming SSL is false as per README example herojobs.NewRedisClient("localhost:6379", false)
|
|
// This might need to be configurable later.
|
|
client, err := herojobs.NewRedisClient(redisAddr, false)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create HeroJobs Redis client: %w", err)
|
|
}
|
|
|
|
return &JobHandler{
|
|
client: client,
|
|
logger: logger,
|
|
}, nil
|
|
}
|
|
|
|
// RegisterRoutes registers job page routes
|
|
func (h *JobHandler) RegisterRoutes(app *fiber.App) {
|
|
// Register routes for /jobs
|
|
jobs := app.Group("/jobs")
|
|
jobs.Get("/", h.getJobsPage)
|
|
jobs.Get("/list", h.getJobsList)
|
|
|
|
// Register the same routes under /admin/jobs for consistency
|
|
adminJobs := app.Group("/admin/jobs")
|
|
adminJobs.Get("/", h.getJobsPage)
|
|
adminJobs.Get("/list", h.getJobsList)
|
|
}
|
|
|
|
// getJobsPage renders the jobs page
|
|
func (h *JobHandler) getJobsPage(c *fiber.Ctx) error {
|
|
// Assuming h.client (RedisClient) is valid if NewJobHandler succeeded.
|
|
// The client is connected on creation. A Ping method could be used here for a health check if available.
|
|
// The previous connect/close logic per-request is removed.
|
|
var warning string // This will be empty unless a new check (e.g., Ping) sets it.
|
|
return c.Render("admin/jobs", fiber.Map{
|
|
"title": "Jobs",
|
|
"warning": warning, // warning will be empty for now
|
|
"error": "",
|
|
})
|
|
}
|
|
|
|
// getJobsList returns the jobs list fragment for AJAX updates
|
|
func (h *JobHandler) getJobsList(c *fiber.Ctx) error {
|
|
// Get parameters from query
|
|
circleID := c.Query("circleid", "")
|
|
topic := c.Query("topic", "")
|
|
|
|
// Get jobs
|
|
jobs, err := h.getJobsData(circleID, topic)
|
|
if err != nil {
|
|
h.logger.Printf("Error getting jobs: %v", err)
|
|
// Return the error in the template
|
|
return c.Render("admin/jobs_list_fragment", fiber.Map{
|
|
"error": fmt.Sprintf("Failed to get jobs: %v", err),
|
|
"jobs": []JobDisplayInfo{},
|
|
})
|
|
}
|
|
|
|
// Render only the jobs fragment
|
|
return c.Render("admin/jobs_list_fragment", fiber.Map{
|
|
"jobs": jobs,
|
|
})
|
|
}
|
|
|
|
// getJobsData gets job data from the HeroJobs server
|
|
func (h *JobHandler) getJobsData(circleID, topic string) ([]JobDisplayInfo, error) {
|
|
// Assuming h.client (RedisClient) is already connected (established by NewJobHandler).
|
|
// It should not be closed here as it's a long-lived client.
|
|
// Connect() and Close() calls per-request are removed.
|
|
|
|
// If circleID and topic are not provided, try to list all jobs
|
|
if circleID == "" && topic == "" {
|
|
// Try to get some default jobs
|
|
defaultCircles := []string{"default", "system"}
|
|
defaultTopics := []string{"default", "system"}
|
|
|
|
var allJobs []JobDisplayInfo
|
|
|
|
// Try each combination
|
|
for _, circle := range defaultCircles {
|
|
for _, t := range defaultTopics {
|
|
jobIDs, err := h.client.ListJobs(circle, t)
|
|
if err != nil {
|
|
h.logger.Printf("Could not list jobs for circle=%s, topic=%s: %v", circle, t, err)
|
|
continue
|
|
}
|
|
|
|
for _, jobID := range jobIDs {
|
|
job, err := h.client.GetJob(jobID)
|
|
if err != nil {
|
|
h.logger.Printf("Error getting job %s: %v", jobID, err)
|
|
continue
|
|
}
|
|
|
|
allJobs = append(allJobs, JobDisplayInfo{
|
|
JobID: fmt.Sprintf("%d", job.JobID),
|
|
CircleID: job.CircleID,
|
|
Topic: job.Topic,
|
|
Status: string(job.Status),
|
|
SessionKey: job.SessionKey,
|
|
Params: job.Params,
|
|
ParamsType: string(job.ParamsType),
|
|
Result: job.Result,
|
|
Error: job.Error,
|
|
TimeScheduled: job.TimeScheduled,
|
|
TimeStart: job.TimeStart,
|
|
TimeEnd: job.TimeEnd,
|
|
Timeout: job.Timeout,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return allJobs, nil
|
|
} else if circleID == "" || topic == "" {
|
|
// If only one of the parameters is provided, we can't list jobs
|
|
return []JobDisplayInfo{}, nil
|
|
}
|
|
|
|
// List jobs
|
|
jobIDs, err := h.client.ListJobs(circleID, topic)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to list jobs: %w", err)
|
|
}
|
|
|
|
// Get details for each job
|
|
jobsList := make([]JobDisplayInfo, 0, len(jobIDs))
|
|
for _, jobID := range jobIDs {
|
|
job, err := h.client.GetJob(jobID)
|
|
if err != nil {
|
|
h.logger.Printf("Error getting job %s: %v", jobID, err)
|
|
continue
|
|
}
|
|
|
|
jobInfo := JobDisplayInfo{
|
|
JobID: fmt.Sprintf("%d", job.JobID),
|
|
CircleID: job.CircleID,
|
|
Topic: job.Topic,
|
|
Status: string(job.Status),
|
|
SessionKey: job.SessionKey,
|
|
Params: job.Params,
|
|
ParamsType: string(job.ParamsType),
|
|
Result: job.Result,
|
|
Error: job.Error,
|
|
TimeScheduled: job.TimeScheduled,
|
|
TimeStart: job.TimeStart,
|
|
TimeEnd: job.TimeEnd,
|
|
Timeout: job.Timeout,
|
|
}
|
|
jobsList = append(jobsList, jobInfo)
|
|
}
|
|
|
|
return jobsList, nil
|
|
}
|