Files
seaweedfs/weed/plugin/worker/interval.go
T
Chris LuandDevin 4ed9595a58 admin: explain detection cooldowns and skipped scans (#12185)
* plugin: describe detection cooldowns and report skipped scans

* admin: expose cooldown eligibility and preserve skipped detection outcomes

* admin: show cooldown eligibility alongside maintenance lock waits

* plugin: retain cooldown activity for older admin servers

* admin: keep manual detection skips out of scheduler run state

* plugin: refresh descriptors on reconnect without downgrading saved schemas

* plugin: allow valid schema refreshes to repair corrupt descriptors

* admin: store eligible_after activity detail as RFC3339

* worker: report admin_script interval skips as skipped detection

* worker: report admin_script interval skips after the last completed job

* admin: show the selected job's cooldown while scheduling is disabled

* admin: report an unsigned interval skip instead of a completed scan

* worker: populate new DetectionComplete fields in Rust senders

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-28 22:55:36 -07:00

45 lines
1.7 KiB
Go

package pluginworker
import (
"fmt"
"time"
"github.com/seaweedfs/seaweedfs/weed/pb/plugin_pb"
"google.golang.org/protobuf/types/known/timestamppb"
)
// ShouldSkipDetectionByInterval returns true when less than minIntervalSeconds
// have elapsed since lastSuccessfulRun. Exported so sub-packages can reuse it.
func ShouldSkipDetectionByInterval(lastSuccessfulRun *timestamppb.Timestamp, minIntervalSeconds int) bool {
if lastSuccessfulRun == nil || minIntervalSeconds <= 0 {
return false
}
lastRun := lastSuccessfulRun.AsTime()
if lastRun.IsZero() {
return false
}
return time.Since(lastRun) < time.Duration(minIntervalSeconds)*time.Second
}
func SkipDetectionByInterval(request *plugin_pb.RunDetectionRequest, sender DetectionSender, minIntervalSeconds int) (bool, error) {
if !ShouldSkipDetectionByInterval(request.GetLastSuccessfulRun(), minIntervalSeconds) {
return false, nil
}
until := request.GetLastSuccessfulRun().AsTime().Add(time.Duration(minIntervalSeconds) * time.Second)
reason := fmt.Sprintf("Cooldown after last completed job (%s)", time.Duration(minIntervalSeconds)*time.Second)
if err := sender.SendActivity(BuildDetectorActivity("skipped_by_interval", reason, map[string]*plugin_pb.ConfigValue{
"eligible_after": {Kind: &plugin_pb.ConfigValue_StringValue{StringValue: until.UTC().Format(time.RFC3339)}},
})); err != nil {
return true, err
}
if err := sender.SendProposals(&plugin_pb.DetectionProposals{JobType: request.GetJobType()}); err != nil {
return true, err
}
return true, sender.SendComplete(&plugin_pb.DetectionComplete{
JobType: request.GetJobType(),
Success: true,
SkippedReason: reason,
EligibleAfter: timestamppb.New(until),
})
}