Update dependencies and clean up project structure. Add cloud.google.com/go/compute/metadata as an indirect requirement in go.mod. Remove unused files and update package.json for Vite and React plugins. Refactor Makefile for improved build process.

This commit is contained in:
2025-11-22 06:53:24 -06:00
parent c9ade39ad9
commit 30aa969433
1295 changed files with 343445 additions and 210041 deletions

View File

@@ -18,6 +18,10 @@ import (
"github.com/gorilla/websocket"
)
type contextKey string
const runnerIDContextKey contextKey = "runner_id"
// handleListRunners lists all runners
func (s *Server) handleListRunners(w http.ResponseWriter, r *http.Request) {
_, err := getUserID(r)
@@ -86,7 +90,7 @@ func (s *Server) runnerAuthMiddleware(next http.HandlerFunc) http.HandlerFunc {
// Add runner ID to context
ctx := r.Context()
ctx = context.WithValue(ctx, "runner_id", runnerID)
ctx = context.WithValue(ctx, runnerIDContextKey, runnerID)
next(w, r.WithContext(ctx))
}
}
@@ -188,7 +192,7 @@ func (s *Server) handleUpdateTaskProgress(w http.ResponseWriter, r *http.Request
// handleUpdateTaskStep handles step start/complete events from runners
func (s *Server) handleUpdateTaskStep(w http.ResponseWriter, r *http.Request) {
// Get runner ID from context (set by runnerAuthMiddleware)
runnerID, ok := r.Context().Value("runner_id").(int64)
runnerID, ok := r.Context().Value(runnerIDContextKey).(int64)
if !ok {
s.respondError(w, http.StatusUnauthorized, "runner_id not found in context")
return
@@ -379,43 +383,6 @@ func (s *Server) handleUploadFileFromRunner(w http.ResponseWriter, r *http.Reque
})
}
// generateMP4Video generates MP4 video from PNG frames for a completed job
func (s *Server) generateMP4Video(jobID int64) {
// This would be called by a runner or external process
// For now, we'll create a special task that runners can pick up
// In a production system, you might want to use a job queue or have a dedicated video processor
// Get all PNG output files for this job
rows, err := s.db.Query(
`SELECT file_path, file_name FROM job_files
WHERE job_id = ? AND file_type = ? AND file_name LIKE '%.png'
ORDER BY file_name`,
jobID, types.JobFileTypeOutput,
)
if err != nil {
log.Printf("Failed to query PNG files for job %d: %v", jobID, err)
return
}
defer rows.Close()
var pngFiles []string
for rows.Next() {
var filePath, fileName string
if err := rows.Scan(&filePath, &fileName); err == nil {
pngFiles = append(pngFiles, filePath)
}
}
if len(pngFiles) == 0 {
log.Printf("No PNG files found for job %d", jobID)
return
}
// Note: Video generation will be handled by runners when they complete tasks
// Runners can check job status and generate MP4 when all frames are complete
log.Printf("Job %d completed with %d PNG frames - ready for MP4 generation", jobID, len(pngFiles))
}
// handleGetJobStatusForRunner allows runners to check job status
func (s *Server) handleGetJobStatusForRunner(w http.ResponseWriter, r *http.Request) {
jobID, err := parseID(r, "jobId")
@@ -632,18 +599,15 @@ func (s *Server) handleRunnerWebSocket(w http.ResponseWriter, r *http.Request) {
go func() {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
s.runnerConnsMu.RLock()
conn, exists := s.runnerConns[runnerID]
s.runnerConnsMu.RUnlock()
if !exists {
return
}
if err := conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(10*time.Second)); err != nil {
return
}
for range ticker.C {
s.runnerConnsMu.RLock()
conn, exists := s.runnerConns[runnerID]
s.runnerConnsMu.RUnlock()
if !exists {
return
}
if err := conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(10*time.Second)); err != nil {
return
}
}
}()

View File

@@ -496,6 +496,9 @@ func (s *Server) recoverTaskTimeouts() {
WHERE id = ?`,
types.TaskStatusFailed, "Task timeout exceeded, max retries reached", taskID,
)
if err != nil {
log.Printf("Failed to mark task %d as failed: %v", taskID, err)
}
} else {
// Reset to pending
_, err = s.db.Exec(

View File

@@ -6,6 +6,7 @@ import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"log"
@@ -496,10 +497,10 @@ func (c *Client) processTask(task map[string]interface{}, jobName, outputFormat
cmd.Dir = workDir
output, err := cmd.CombinedOutput()
if err != nil {
errMsg := fmt.Sprintf("blender failed: %w\nOutput: %s", err, string(output))
errMsg := fmt.Sprintf("blender failed: %v\nOutput: %s", err, string(output))
c.sendLog(taskID, types.LogLevelError, errMsg, "render_blender")
c.sendStepUpdate(taskID, "render_blender", types.StepStatusFailed, errMsg)
return fmt.Errorf(errMsg)
return errors.New(errMsg)
}
// Find rendered output file
@@ -508,7 +509,7 @@ func (c *Client) processTask(task map[string]interface{}, jobName, outputFormat
errMsg := fmt.Sprintf("output file not found: %s", outputFile)
c.sendLog(taskID, types.LogLevelError, errMsg, "render_blender")
c.sendStepUpdate(taskID, "render_blender", types.StepStatusFailed, errMsg)
return fmt.Errorf(errMsg)
return errors.New(errMsg)
}
c.sendLog(taskID, types.LogLevelInfo, fmt.Sprintf("Blender render completed for frame %d", frameStart), "render_blender")
c.sendStepUpdate(taskID, "render_blender", types.StepStatusCompleted, "")
@@ -523,10 +524,10 @@ func (c *Client) processTask(task map[string]interface{}, jobName, outputFormat
outputPath, err := c.uploadFile(jobID, outputFile)
if err != nil {
errMsg := fmt.Sprintf("failed to upload output: %w", err)
errMsg := fmt.Sprintf("failed to upload output: %v", err)
c.sendLog(taskID, types.LogLevelError, errMsg, uploadStepName)
c.sendStepUpdate(taskID, uploadStepName, types.StepStatusFailed, errMsg)
return fmt.Errorf(errMsg)
return errors.New(errMsg)
}
c.sendLog(taskID, types.LogLevelInfo, "Output file uploaded successfully", uploadStepName)
c.sendStepUpdate(taskID, uploadStepName, types.StepStatusCompleted, "")
@@ -1001,10 +1002,10 @@ sys.stdout.flush()
cmd.Dir = workDir
output, err := cmd.CombinedOutput()
if err != nil {
errMsg := fmt.Sprintf("blender metadata extraction failed: %w\nOutput: %s", err, string(output))
errMsg := fmt.Sprintf("blender metadata extraction failed: %v\nOutput: %s", err, string(output))
c.sendLog(taskID, types.LogLevelError, errMsg, "extract_metadata")
c.sendStepUpdate(taskID, "extract_metadata", types.StepStatusFailed, errMsg)
return fmt.Errorf(errMsg)
return errors.New(errMsg)
}
// Parse output (metadata is printed to stdout)
@@ -1016,16 +1017,16 @@ sys.stdout.flush()
errMsg := "Failed to extract JSON from Blender output"
c.sendLog(taskID, types.LogLevelError, errMsg, "extract_metadata")
c.sendStepUpdate(taskID, "extract_metadata", types.StepStatusFailed, errMsg)
return fmt.Errorf(errMsg)
return errors.New(errMsg)
}
metadataJSON = metadataJSON[jsonStart : jsonEnd+1]
var metadata types.BlendMetadata
if err := json.Unmarshal([]byte(metadataJSON), &metadata); err != nil {
errMsg := fmt.Sprintf("Failed to parse metadata JSON: %w", err)
errMsg := fmt.Sprintf("Failed to parse metadata JSON: %v", err)
c.sendLog(taskID, types.LogLevelError, errMsg, "extract_metadata")
c.sendStepUpdate(taskID, "extract_metadata", types.StepStatusFailed, errMsg)
return fmt.Errorf(errMsg)
return errors.New(errMsg)
}
c.sendLog(taskID, types.LogLevelInfo, fmt.Sprintf("Metadata extracted: frames %d-%d, resolution %dx%d",
@@ -1038,10 +1039,10 @@ sys.stdout.flush()
// Submit metadata to manager
if err := c.submitMetadata(jobID, metadata); err != nil {
errMsg := fmt.Sprintf("Failed to submit metadata: %w", err)
errMsg := fmt.Sprintf("Failed to submit metadata: %v", err)
c.sendLog(taskID, types.LogLevelError, errMsg, "submit_metadata")
c.sendStepUpdate(taskID, "submit_metadata", types.StepStatusFailed, errMsg)
return fmt.Errorf(errMsg)
return errors.New(errMsg)
}
c.sendStepUpdate(taskID, "submit_metadata", types.StepStatusCompleted, "")