Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE trax.manifest ADD COLUMN IF NOT EXISTS variance_seconds integer;
ALTER TABLE trax.manifest ADD COLUMN IF NOT EXISTS next_scheduled_run timestamp without time zone;
6 changes: 6 additions & 0 deletions src/Trax.Effect/Models/Manifest/DTOs/CreateManifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,11 @@ public class CreateManifest
/// </summary>
public string? Exclusions { get; set; }

/// <summary>
/// Maximum random delay in seconds added to each scheduled run.
/// Null means no variance (deterministic scheduling).
/// </summary>
public int? VarianceSeconds { get; set; }

#endregion
}
27 changes: 27 additions & 0 deletions src/Trax.Effect/Models/Manifest/Manifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,32 @@ public class Manifest : IModel
[Column("exclusions")]
public string? Exclusions { get; set; }

/// <summary>
/// Gets or sets the maximum random delay in seconds added to each scheduled run.
/// </summary>
/// <remarks>
/// When set, after each successful execution the scheduler computes the next run time
/// as <c>baseSchedule + Random(0, VarianceSeconds)</c> and stores it in
/// <see cref="NextScheduledRun"/>. This prevents thundering-herd problems and makes
/// scraping patterns less detectable. Only applies to Cron and Interval schedule types.
/// Null means no variance (deterministic scheduling).
/// </remarks>
[Column("variance_seconds")]
public int? VarianceSeconds { get; set; }

/// <summary>
/// Gets or sets the pre-computed next execution time including any applied variance.
/// </summary>
/// <remarks>
/// Set automatically by the scheduler after each successful run when
/// <see cref="VarianceSeconds"/> is configured. The ManifestManager uses this value
/// instead of computing the next run time on-the-fly, ensuring deterministic behavior
/// across polling cycles. Null means the scheduler computes the next run time from
/// <see cref="LastSuccessfulRun"/> and the schedule definition.
/// </remarks>
[Column("next_scheduled_run")]
public DateTime? NextScheduledRun { get; set; }

#endregion

#endregion
Expand Down Expand Up @@ -288,6 +314,7 @@ public static Manifest Create(CreateManifest manifest)
MisfireThresholdSeconds = manifest.MisfireThresholdSeconds,
ScheduledAt = manifest.ScheduledAt,
Exclusions = manifest.Exclusions,
VarianceSeconds = manifest.VarianceSeconds,
};

if (manifest.Properties != null)
Expand Down
Loading