@
feat: make per-job timeout 0 mean "no timeout" instead of inherit A per-job timeout now has three distinct states: unset inherits the global default, an explicit 0 means no timeout and does not inherit, and a positive value is the per-job limit. Job.TimeoutSeconds became *int so unset and 0 stay distinguishable in jobs.json. Also fixes the global default, which could not persist a 0. loadOrCreateConfig normalized DefaultTimeoutSeconds <= 0 back to 30 on every read of an existing gosentry.json, so "no timeout" only held until the next restart. The field is now written unconditionally (no omitempty) and read back as-is. Existing jobs and configs are unaffected: a job with no timeout_seconds still inherits, and a saved global default of 30 stays 30. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> @
This commit is contained in:
@@ -55,9 +55,9 @@ func showJobDialog(w fyne.Window, title string, current job, onSave func(job)) {
|
||||
}
|
||||
overlapSelect.SetSelected(overlapSelected)
|
||||
timeoutEntry := widget.NewEntry()
|
||||
timeoutEntry.SetPlaceHolder("Empty = use global default")
|
||||
if current.TimeoutSeconds > 0 {
|
||||
timeoutEntry.SetText(strconv.Itoa(current.TimeoutSeconds))
|
||||
timeoutEntry.SetPlaceHolder("Empty = global default, 0 = no timeout")
|
||||
if current.TimeoutSeconds != nil {
|
||||
timeoutEntry.SetText(strconv.Itoa(*current.TimeoutSeconds))
|
||||
}
|
||||
|
||||
form := dialog.NewForm(
|
||||
@@ -89,16 +89,17 @@ func showJobDialog(w fyne.Window, title string, current job, onSave func(job)) {
|
||||
dialog.ShowError(fmt.Errorf("invalid schedule: %w", err), w)
|
||||
return
|
||||
}
|
||||
// An empty timeout inherits the global default (0); any entry must be a
|
||||
// An empty timeout inherits the global default (nil); an explicit 0
|
||||
// means "no timeout" and does not inherit; anything else must be a
|
||||
// positive whole number of seconds.
|
||||
timeoutSeconds := 0
|
||||
var timeoutSeconds *int
|
||||
if trimmed := strings.TrimSpace(timeoutEntry.Text); trimmed != "" {
|
||||
parsed, err := strconv.Atoi(trimmed)
|
||||
if err != nil || parsed <= 0 {
|
||||
dialog.ShowError(fmt.Errorf("timeout must be a positive number of seconds, or empty to use the global default"), w)
|
||||
if err != nil || parsed < 0 {
|
||||
dialog.ShowError(fmt.Errorf("timeout must be 0 (no timeout) or a positive number of seconds, or empty to use the global default"), w)
|
||||
return
|
||||
}
|
||||
timeoutSeconds = parsed
|
||||
timeoutSeconds = domain.TimeoutSecondsPtr(parsed)
|
||||
}
|
||||
current.Name = strings.TrimSpace(name.Text)
|
||||
current.Folder = strings.TrimSpace(folderEntry.Text)
|
||||
|
||||
Reference in New Issue
Block a user