Budgetende, Stufe 1: Ausfall vermerken, Regel je Agent, mitnehmen statt anrennen (#716)
Bisher teilte sich eine Budgetablehnung den Ausgang NichtGelaufen mit dem Herunterfahren. Einmalige Aufgaben wurden den Rest des Tages alle 30 Minuten erneut abgelehnt (jedes Mal ein Beleg) und liefen nach Mitternacht still zu Lasten des neuen Tages. Wiederkehrende verfielen still. - TaskLauf.KeinBudget als eigener Ausgang; der Dispatcher bildet BudgetExceeded darauf ab. - Vier Felder an der Aufgabe: BudgetMissCount, LastBudgetMissAt, DeferredUntil, CatchUpPending (Spalten werden fuer bestehende Datenbanken nachgeruestet). - Einmalige Aufgaben werden mitgenommen: Der Termin bleibt erhalten, faellig ist die Aufgabe wieder ab der naechsten lokalen Mitternacht, nicht vorher. - Wiederkehrende Aufgaben folgen der Regel des Agenten (budget.whenExhausted): expire vermerkt den Ausfall und laesst den Termin verfallen; catchUpOnce fasst alle verpassten Termine zu einem Nachholauf am naechsten Tag zusammen. Ein regulaer faelliger Termin deckt das Nachholen mit ab, es bleibt bei einem Lauf. - Der neue Tag hat Vorfahrt: Mitgenommenes und Nachholaeufe kommen nach allem regulaer Faelligen, unabhaengig von der Prioritaet. - Beim ersten Takt eines neuen Tages eine Zusammenfassung je Agent im Log. - Sichtbar: Die Aufgabenkarte der WebUI zeigt Ausfaelle, Mitnahme und Nachholen; die Regel ist im Desktop je Agent einstellbar. Nebenbei sind "Next:"/"Last:" auf der Karte ins Sprachpaket gewandert. Stufen 2 bis 4 (Reservierung, Spielraum statt pauschalem Anteil, Vorbeugen) folgen. Tests: BudgetMissTests (9 neu). 1.238 gruen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b53396a754
commit
5f3a85595b
@@ -205,6 +205,32 @@ public sealed record TaskItem
|
||||
public DateTime CreatedAt { get; init; }
|
||||
public DateTime UpdatedAt { get; init; }
|
||||
|
||||
// ─── Budget misses (#716) ───
|
||||
|
||||
/// <summary>
|
||||
/// How many times in a row a run of this task was refused because the budget was
|
||||
/// exhausted. Reset by the next run that actually takes place.
|
||||
/// </summary>
|
||||
public int BudgetMissCount { get; init; }
|
||||
|
||||
/// <summary>When the last budget refusal happened (UTC). Kept after a reset, as history.</summary>
|
||||
public DateTime? LastBudgetMissAt { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Not before this point (UTC). Set after a budget refusal to the start of the next
|
||||
/// local day: retrying within the same day only produces further refusals.
|
||||
/// </summary>
|
||||
public DateTime? DeferredUntil { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// A recurring task under <see cref="BudgetMissPolicy.CatchUpOnce"/> missed at least
|
||||
/// one occurrence; all of them are caught up by a single run.
|
||||
/// </summary>
|
||||
public bool CatchUpPending { get; init; }
|
||||
|
||||
/// <summary>A one-time task that was refused for lack of budget and carried over.</summary>
|
||||
public bool IsCarriedOver => !IsRecurring && BudgetMissCount > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Wiederkehrend? Solche Tasks kehren nach dem Feuern auf <c>todo</c> zurück statt auf
|
||||
/// <c>done</c> — sonst würde ein Cron-Task nur ein einziges Mal laufen. Ein
|
||||
@@ -215,6 +241,19 @@ public sealed record TaskItem
|
||||
|| When is { Kind: TaskWhenKind.Cron or TaskWhenKind.Every };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// #716: What happens to a run of a recurring task that the budget refused. One-time
|
||||
/// tasks are always carried over — they are real work that must not disappear.
|
||||
/// </summary>
|
||||
public enum BudgetMissPolicy
|
||||
{
|
||||
/// <summary>The occurrence lapses and is recorded; the next regular one comes anyway.</summary>
|
||||
Expire,
|
||||
|
||||
/// <summary>All missed occurrences are caught up by one run on the next day.</summary>
|
||||
CatchUpOnce
|
||||
}
|
||||
|
||||
/// <summary>Suchkriterien für <see cref="ITaskRepository.ListAsync"/>.</summary>
|
||||
public sealed record TaskQuery
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user