216 lines
5.2 KiB
Go
216 lines
5.2 KiB
Go
// backend\tasks_status.go
|
|
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type CleanupTaskState struct {
|
|
Running bool `json:"running"`
|
|
Done int `json:"done"`
|
|
Total int `json:"total"`
|
|
Text string `json:"text,omitempty"`
|
|
CurrentFile string `json:"currentFile,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
FinishedAt *string `json:"finishedAt,omitempty"`
|
|
}
|
|
|
|
type RegenerateAssetsTaskState struct {
|
|
Running bool `json:"running"`
|
|
File string `json:"file,omitempty"`
|
|
Text string `json:"text,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
type TasksStatusResponse struct {
|
|
GenerateAssets AssetsTaskState `json:"generateAssets"`
|
|
RegenerateAssets RegenerateAssetsTaskState `json:"regenerateAssets"`
|
|
RegenerateAssetsJobs []map[string]any `json:"regenerateAssetsJobs"`
|
|
Cleanup CleanupTaskState `json:"cleanup"`
|
|
AnyRunning bool `json:"anyRunning"`
|
|
}
|
|
|
|
var (
|
|
cleanupTaskMu sync.Mutex
|
|
cleanupTaskState CleanupTaskState
|
|
|
|
regenerateAssetsTaskMu sync.Mutex
|
|
regenerateAssetsTaskState RegenerateAssetsTaskState
|
|
)
|
|
|
|
func cleanupNowISO() *string {
|
|
s := time.Now().Format(time.RFC3339)
|
|
return &s
|
|
}
|
|
|
|
func anyToString(v any) string {
|
|
switch x := v.(type) {
|
|
case string:
|
|
return x
|
|
case []byte:
|
|
return string(x)
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func snapshotRegenerateAssetsTaskState() RegenerateAssetsTaskState {
|
|
regenerateAssetsTaskMu.Lock()
|
|
st := regenerateAssetsTaskState
|
|
regenerateAssetsTaskMu.Unlock()
|
|
return st
|
|
}
|
|
|
|
func setRegenerateAssetsTaskRunning(file, text string) {
|
|
regenerateAssetsTaskMu.Lock()
|
|
regenerateAssetsTaskState = RegenerateAssetsTaskState{
|
|
Running: true,
|
|
File: strings.TrimSpace(file),
|
|
Text: strings.TrimSpace(text),
|
|
Error: "",
|
|
}
|
|
regenerateAssetsTaskMu.Unlock()
|
|
|
|
publishTaskState()
|
|
}
|
|
|
|
func setRegenerateAssetsTaskDone(file, text string) {
|
|
regenerateAssetsTaskMu.Lock()
|
|
regenerateAssetsTaskState = RegenerateAssetsTaskState{
|
|
Running: false,
|
|
File: strings.TrimSpace(file),
|
|
Text: strings.TrimSpace(text),
|
|
Error: "",
|
|
}
|
|
regenerateAssetsTaskMu.Unlock()
|
|
|
|
publishTaskState()
|
|
}
|
|
|
|
func setRegenerateAssetsTaskError(file, errText string) {
|
|
regenerateAssetsTaskMu.Lock()
|
|
regenerateAssetsTaskState = RegenerateAssetsTaskState{
|
|
Running: false,
|
|
File: strings.TrimSpace(file),
|
|
Text: "",
|
|
Error: strings.TrimSpace(errText),
|
|
}
|
|
regenerateAssetsTaskMu.Unlock()
|
|
|
|
publishTaskState()
|
|
}
|
|
|
|
func clearRegenerateAssetsTaskState() {
|
|
regenerateAssetsTaskMu.Lock()
|
|
regenerateAssetsTaskState = RegenerateAssetsTaskState{}
|
|
regenerateAssetsTaskMu.Unlock()
|
|
|
|
publishTaskState()
|
|
}
|
|
|
|
func snapshotCleanupTaskState() CleanupTaskState {
|
|
cleanupTaskMu.Lock()
|
|
st := cleanupTaskState
|
|
cleanupTaskMu.Unlock()
|
|
return st
|
|
}
|
|
|
|
func setCleanupTaskRunning(text string) {
|
|
cleanupTaskMu.Lock()
|
|
cleanupTaskState = CleanupTaskState{
|
|
Running: true,
|
|
Done: 0,
|
|
Total: 0,
|
|
Text: strings.TrimSpace(text),
|
|
CurrentFile: "",
|
|
Error: "",
|
|
FinishedAt: nil,
|
|
}
|
|
cleanupTaskMu.Unlock()
|
|
|
|
publishTaskState()
|
|
}
|
|
|
|
func setCleanupTaskProgress(done, total int, currentFile, text string) {
|
|
cleanupTaskMu.Lock()
|
|
cleanupTaskState.Running = true
|
|
cleanupTaskState.Done = done
|
|
cleanupTaskState.Total = total
|
|
cleanupTaskState.CurrentFile = strings.TrimSpace(currentFile)
|
|
cleanupTaskState.Text = strings.TrimSpace(text)
|
|
cleanupTaskState.Error = ""
|
|
cleanupTaskState.FinishedAt = nil
|
|
cleanupTaskMu.Unlock()
|
|
|
|
publishTaskState()
|
|
}
|
|
|
|
func setCleanupTaskDone(text string) {
|
|
cleanupTaskMu.Lock()
|
|
cleanupTaskState.Running = false
|
|
cleanupTaskState.Text = strings.TrimSpace(text)
|
|
cleanupTaskState.CurrentFile = ""
|
|
cleanupTaskState.Error = ""
|
|
cleanupTaskState.FinishedAt = cleanupNowISO()
|
|
|
|
if cleanupTaskState.Total > 0 {
|
|
cleanupTaskState.Done = cleanupTaskState.Total
|
|
}
|
|
|
|
cleanupTaskMu.Unlock()
|
|
|
|
publishTaskState()
|
|
}
|
|
|
|
func setCleanupTaskError(errText string) {
|
|
cleanupTaskMu.Lock()
|
|
cleanupTaskState.Running = false
|
|
cleanupTaskState.Text = ""
|
|
cleanupTaskState.Error = strings.TrimSpace(errText)
|
|
cleanupTaskState.CurrentFile = ""
|
|
cleanupTaskState.FinishedAt = cleanupNowISO()
|
|
cleanupTaskMu.Unlock()
|
|
|
|
publishTaskState()
|
|
}
|
|
|
|
func tasksStatusHandler(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
http.Error(w, "Nur GET erlaubt", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
|
|
assets := getGenerateAssetsTaskStatus()
|
|
regenerate := snapshotRegenerateAssetsTaskState()
|
|
regenerateJobs := getRegenerateAssetsJobsSnapshot()
|
|
cleanup := snapshotCleanupTaskState()
|
|
|
|
anyRegenerateRunning := regenerate.Running
|
|
if !anyRegenerateRunning {
|
|
for _, job := range regenerateJobs {
|
|
state := strings.TrimSpace(strings.ToLower(anyToString(job["state"])))
|
|
if state == "queued" || state == "running" {
|
|
anyRegenerateRunning = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
resp := TasksStatusResponse{
|
|
GenerateAssets: assets,
|
|
RegenerateAssets: regenerate,
|
|
RegenerateAssetsJobs: regenerateJobs,
|
|
Cleanup: cleanup,
|
|
AnyRunning: assets.Queued || assets.Running || anyRegenerateRunning || cleanup.Running,
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Cache-Control", "no-store")
|
|
_ = json.NewEncoder(w).Encode(resp)
|
|
}
|