diff --git a/pkg/atproto/sweep.go b/pkg/atproto/sweep.go index 089291f7f..a5faea716 100644 --- a/pkg/atproto/sweep.go +++ b/pkg/atproto/sweep.go @@ -452,6 +452,11 @@ func (atsync *ATProtoSynchronizer) sweepBootDelay(ctx context.Context) time.Dura delay := config.DefaultSweepBootDelay if atsync.CLI != nil { delay = atsync.CLI.SweepBootDelay + if atsync.CLI.NoFirehose { + // No firehose means no replay to heal the restart's gap: the boot + // sweep is this node's only reconciliation, so it does not wait. + return 0 + } } if delay <= 0 { return 0 diff --git a/pkg/atproto/sweep_test.go b/pkg/atproto/sweep_test.go index ebedfb0a9..77dd900ba 100644 --- a/pkg/atproto/sweep_test.go +++ b/pkg/atproto/sweep_test.go @@ -816,6 +816,12 @@ func TestSweepBootDelay(t *testing.T) { require.NoError(t, mod.UpdateRepo(&model.Repo{DID: "did:plc:warmbootdelaytest", Version: "rev"})) require.Equal(t, 42*time.Minute, atsync.sweepBootDelay(ctx), "a warm index waits") + atsync.CLI.SweepBootDelay = 42 * time.Minute + atsync.CLI.NoFirehose = true + require.Equal(t, time.Duration(0), atsync.sweepBootDelay(ctx), + "without a firehose there is no replay to heal the gap; the sweep is all this node has") + atsync.CLI.NoFirehose = false + atsync.CLI.SweepBootDelay = 0 require.Equal(t, time.Duration(0), atsync.sweepBootDelay(ctx), "0 disables the hold") } diff --git a/pkg/config/config.go b/pkg/config/config.go index c8ba77470..e63134ea4 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -882,7 +882,7 @@ func (cli *CLI) NewCommand(name string) *urfavecli.Command { }, &urfavecli.DurationFlag{ Name: "sweep-boot-delay", - Usage: "how long a node with a warm index waits after boot before its first sweep, so the sweep's reindexing does not compound the busiest minutes of a restart. A fresh (empty) index always sweeps immediately, and 0 sweeps immediately in every case", + Usage: "how long a node with a warm index waits after boot before its first sweep, so the sweep's reindexing does not compound the busiest minutes of a restart. A fresh (empty) index always sweeps immediately, as does a --no-firehose node (no replay heals its gap), and 0 sweeps immediately in every case", Value: DefaultSweepBootDelay, Destination: &cli.SweepBootDelay, Sources: urfavecli.EnvVars("SP_SWEEP_BOOT_DELAY"),