Plugin scheduler: sequential iterations with max runtime (#8496)
* pb: add job type max runtime setting * plugin: default job type max runtime * plugin: redesign scheduler loop * admin ui: update scheduler settings * plugin: fix scheduler loop state name * plugin scheduler: restore backlog skip * plugin scheduler: drop legacy detection helper * admin api: require scheduler config body * admin ui: preserve detection interval on save * plugin scheduler: use job context and drain cancels * plugin scheduler: respect detection intervals * plugin scheduler: gate runs and drain queue * ec test: reuse req/resp vars * ec test: add scheduler debug logs * Adjust scheduler idle sleep and initial run delay * Clear pending job queue before scheduler runs * Log next detection time in EC integration test * Improve plugin scheduler debug logging in EC test * Expose scheduler next detection time * Log scheduler next detection time in EC test * Wake scheduler on config or worker updates * Expose scheduler sleep interval in UI * Fix scheduler sleep save value selection * Set scheduler idle sleep default to 613s * Show scheduler next run time in plugin UI --------- Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -235,6 +235,53 @@ func (s *AdminServer) GetPluginSchedulerStatusAPI(w http.ResponseWriter, r *http
|
||||
writeJSON(w, http.StatusOK, response)
|
||||
}
|
||||
|
||||
// GetPluginSchedulerConfigAPI returns scheduler configuration.
|
||||
func (s *AdminServer) GetPluginSchedulerConfigAPI(w http.ResponseWriter, r *http.Request) {
|
||||
pluginSvc := s.GetPlugin()
|
||||
if pluginSvc == nil {
|
||||
writeJSONError(w, http.StatusNotFound, "plugin is not enabled")
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, pluginSvc.GetSchedulerConfig())
|
||||
}
|
||||
|
||||
// UpdatePluginSchedulerConfigAPI updates scheduler configuration.
|
||||
func (s *AdminServer) UpdatePluginSchedulerConfigAPI(w http.ResponseWriter, r *http.Request) {
|
||||
pluginSvc := s.GetPlugin()
|
||||
if pluginSvc == nil {
|
||||
writeJSONError(w, http.StatusNotFound, "plugin is not enabled")
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
IdleSleepSeconds *int32 `json:"idle_sleep_seconds"`
|
||||
}
|
||||
|
||||
if err := decodeJSONBody(newJSONMaxReader(w, r), &req); err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
writeJSONError(w, http.StatusBadRequest, "request body is required")
|
||||
return
|
||||
}
|
||||
writeJSONError(w, http.StatusBadRequest, "invalid request body: "+err.Error())
|
||||
return
|
||||
}
|
||||
if req.IdleSleepSeconds == nil {
|
||||
writeJSONError(w, http.StatusBadRequest, "idle_sleep_seconds is required")
|
||||
return
|
||||
}
|
||||
|
||||
updated, err := pluginSvc.UpdateSchedulerConfig(plugin.SchedulerConfig{
|
||||
IdleSleepSeconds: *req.IdleSleepSeconds,
|
||||
})
|
||||
if err != nil {
|
||||
writeJSONError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, updated)
|
||||
}
|
||||
|
||||
// RequestPluginJobTypeSchemaAPI asks a worker for one job type schema.
|
||||
func (s *AdminServer) RequestPluginJobTypeSchemaAPI(w http.ResponseWriter, r *http.Request) {
|
||||
jobType := strings.TrimSpace(mux.Vars(r)["jobType"])
|
||||
@@ -867,6 +914,9 @@ func applyDescriptorDefaultsToPersistedConfig(
|
||||
if runtime.PerWorkerExecutionConcurrency <= 0 {
|
||||
runtime.PerWorkerExecutionConcurrency = defaults.PerWorkerExecutionConcurrency
|
||||
}
|
||||
if runtime.JobTypeMaxRuntimeSeconds <= 0 {
|
||||
runtime.JobTypeMaxRuntimeSeconds = defaults.JobTypeMaxRuntimeSeconds
|
||||
}
|
||||
if runtime.RetryBackoffSeconds <= 0 {
|
||||
runtime.RetryBackoffSeconds = defaults.RetryBackoffSeconds
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user