mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-08 04:57:50 +01:00
* feat(s3/lifecycle): operator-declared meta-log retention activates PromotedHash dailyrun.Config.RetentionWindow has been wired since Phase 4b but the handler never supplied a value, so runShard always fell back to maxTTL and engine.PromotedHash hashed nothing. The partition-flip recovery trigger was dormant by design "until the handler plumbs the real meta-log retention here." This PR plumbs it via a new admin form field: Meta-Log Retention (days) — 0 = unbounded (current behavior). When set, ParseConfig converts days to a time.Duration on cfg.MetaLogRetention. The handler passes it as dailyrun.Config.RetentionWindow, which runShard then feeds to engine.PromotedHash. Rules whose TTL exceeds the declared window land in the walk partition; the next time an operator shrinks retention so a previously replay-eligible rule slips past it, PromotedHash mismatches → recovery branch fires → walker re-evaluates the rule across the whole filer tree. 0 stays the default, so existing deployments see no behavior change. * chore(s3/lifecycle): rephrase days->duration conversion gemini-code-assist flagged the original form as a compile error, which it wasn't (time.Duration is a named int64 and supports * with other time.Durations — the test suite verified the value was correct). The suggested form is more idiomatic regardless: days*24 happens in int64 space before the lift to time.Duration, so the unit is unambiguous.
57 lines
1.5 KiB
Go
57 lines
1.5 KiB
Go
package s3_lifecycle
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/plugin_pb"
|
|
)
|
|
|
|
const (
|
|
jobType = "s3_lifecycle"
|
|
|
|
// In-process fan-out across the 16 shards.
|
|
shardPipelineGoroutines = 1
|
|
|
|
defaultMaxRuntimeMinutes = int64(60)
|
|
)
|
|
|
|
type Config struct {
|
|
Workers int
|
|
MaxRuntime time.Duration
|
|
MetaLogRetention time.Duration
|
|
}
|
|
|
|
func ParseConfig(adminValues map[string]*plugin_pb.ConfigValue, workerValues map[string]*plugin_pb.ConfigValue) Config {
|
|
cfg := Config{
|
|
Workers: shardPipelineGoroutines,
|
|
MaxRuntime: time.Duration(readInt64(workerValues, "max_runtime_minutes", defaultMaxRuntimeMinutes)) * time.Minute,
|
|
}
|
|
if cfg.MaxRuntime <= 0 {
|
|
cfg.MaxRuntime = time.Duration(defaultMaxRuntimeMinutes) * time.Minute
|
|
}
|
|
// Operator-declared meta-log retention. Negative or zero values stay
|
|
// zero so runShard falls back to maxTTL (PromotedHash dormant).
|
|
// Convert days->hours in int64 space before lifting to time.Duration
|
|
// so the unit is unambiguous.
|
|
if days := readInt64(adminValues, MetaLogRetentionDaysAdminKey, 0); days > 0 {
|
|
cfg.MetaLogRetention = time.Duration(days*24) * time.Hour
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func readInt64(values map[string]*plugin_pb.ConfigValue, field string, fallback int64) int64 {
|
|
v, ok := values[field]
|
|
if !ok || v == nil {
|
|
return fallback
|
|
}
|
|
switch k := v.Kind.(type) {
|
|
case *plugin_pb.ConfigValue_Int64Value:
|
|
return k.Int64Value
|
|
case *plugin_pb.ConfigValue_DoubleValue:
|
|
return int64(k.DoubleValue)
|
|
case *plugin_pb.ConfigValue_StringValue:
|
|
return fallback
|
|
}
|
|
return fallback
|
|
}
|