feat(s3/lifecycle): enable scheduler by default (#9492)

S3 lifecycle is a standard bucket feature — operators set
PutBucketLifecycleConfiguration through the S3 API expecting the
configured expirations to actually fire. With the prior default
(scheduler enabled=false), buckets with lifecycle XML silently
retained data past their declared expiration until an operator
noticed and turned the scheduler on.

The failure mode of enabled-by-default is "worker runs every day
and fast-exits on buckets with no lifecycle rules" — cheap.
The failure mode of disabled-by-default is "data lingers, looks
like it expired, doesn't" — bad. Enabled-by-default matches both
the AWS S3 default behavior and the operator's natural mental
model.

Operators who want the worker off can still disable it via the
admin UI; once a persisted config exists, this descriptor default
no longer applies (the persisted Enabled state wins).

Test pins the choice so a future flip to false fails loud.
This commit is contained in:
Chris Lu
2026-05-13 16:57:10 -07:00
committed by GitHub
parent 453c735d02
commit 813f1351f8
2 changed files with 23 additions and 0 deletions
@@ -143,6 +143,15 @@ func (h *Handler) Descriptor() *plugin_pb.JobTypeDescriptor {
},
},
AdminRuntimeDefaults: &plugin_pb.AdminRuntimeDefaults{
// On by default: S3 lifecycle is a standard bucket feature
// (PutBucketLifecycleConfiguration is part of the S3 API),
// and a bucket with rules set but no worker running silently
// retains data past its declared expiration. Operators who
// want the worker off can still disable it in the admin UI;
// the default error is "data lingers" not "worker burns CPU
// on empty rule sets" (the worker fast-exits with no
// configured rules).
Enabled: true,
DetectionIntervalMinutes: 24 * 60, // daily
DetectionTimeoutSeconds: 60,
MaxJobsPerDetection: 1,
@@ -348,6 +348,20 @@ func TestDescriptor_AdminRuntimeDefaultsDailyCadence(t *testing.T) {
assert.Equal(t, int32(1), d.AdminRuntimeDefaults.MaxJobsPerDetection)
}
func TestDescriptor_AdminRuntimeDefaultsEnabledByDefault(t *testing.T) {
// S3 lifecycle is a standard bucket feature — operators set
// PutBucketLifecycleConfiguration expecting it to actually fire.
// Default-off would silently retain data past declared expiration
// until an operator notices and flips it on. Document the choice
// here so a future change to disabled-by-default fails the test
// and surfaces a conscious revisit.
h := NewHandler(nil)
d := h.Descriptor()
require.NotNil(t, d.AdminRuntimeDefaults)
assert.True(t, d.AdminRuntimeDefaults.Enabled,
"s3_lifecycle defaults must enable the scheduler so configured rules fire without operator opt-in")
}
// ---------- Execute ----------
// recordingExecSender captures Execute-side messages. The Execute path