fix: persist indexer max_index_time_window_secs setting (#8821)

* fix: persist indexer max_index_time_window_secs setting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: toggle UX for indexer time window cap

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ruben Fiszel
2026-04-13 19:56:38 -04:00
committed by GitHub
parent 89c8e4bb96
commit 4dc54ca3aa
3 changed files with 61 additions and 30 deletions

View File

@@ -436,6 +436,8 @@ pub struct IndexerSettings {
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub max_indexed_job_log_size: Option<u64>, pub max_indexed_job_log_size: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub max_index_time_window_secs: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub should_clear_job_index: Option<bool>, pub should_clear_job_index: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub should_clear_log_index: Option<bool>, pub should_clear_log_index: Option<bool>,

View File

@@ -80,6 +80,7 @@ export interface Setting {
export type SettingStorage = 'setting' export type SettingStorage = 'setting'
const positiveNumber = z.number().positive('Must be a positive number') const positiveNumber = z.number().positive('Must be a positive number')
const nonNegativeNumber = z.number().nonnegative('Must be zero or a positive number')
const indexerSettingsSchema = z const indexerSettingsSchema = z
.object({ .object({
@@ -89,7 +90,7 @@ const indexerSettingsSchema = z
max_indexed_job_log_size: positiveNumber.optional(), max_indexed_job_log_size: positiveNumber.optional(),
commit_log_max_batch_size: positiveNumber.optional(), commit_log_max_batch_size: positiveNumber.optional(),
refresh_log_index_period: positiveNumber.optional(), refresh_log_index_period: positiveNumber.optional(),
max_index_time_window_secs: positiveNumber.optional() max_index_time_window_secs: nonNegativeNumber.optional()
}) })
.passthrough() .passthrough()

View File

@@ -9,6 +9,7 @@
import IntegerInput from '../IntegerInput.svelte' import IntegerInput from '../IntegerInput.svelte'
import InputError from '../InputError.svelte' import InputError from '../InputError.svelte'
import Label from '../Label.svelte' import Label from '../Label.svelte'
import Toggle from '../Toggle.svelte'
import { Loader2, RefreshCw } from 'lucide-svelte' import { Loader2, RefreshCw } from 'lucide-svelte'
import type { Writable } from 'svelte/store' import type { Writable } from 'svelte/store'
@@ -20,6 +21,20 @@
let { values, disabled = false, errors = {} }: Props = $props() let { values, disabled = false, errors = {} }: Props = $props()
let isTimeWindowCapped = $derived($values['indexer_settings'].max_index_time_window_secs !== 0)
function setTimeWindowCapped(checked: boolean) {
if (checked) {
const { max_index_time_window_secs: _, ...rest } = $values['indexer_settings']
$values['indexer_settings'] = rest
} else {
$values['indexer_settings'] = {
...$values['indexer_settings'],
max_index_time_window_secs: 0
}
}
}
let clearJobsIndexModalOpen = $state(false) let clearJobsIndexModalOpen = $state(false)
let clearServiceLogsIndexModalOpen = $state(false) let clearServiceLogsIndexModalOpen = $state(false)
@@ -91,36 +106,49 @@
/> />
<InputError error={errors.writer_memory_budget ?? ''} /> <InputError error={errors.writer_memory_budget ?? ''} />
</div> </div>
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-2">
<label for="max_index_time_window_secs" class="block text-xs font-semibold text-emphasis"> <div class="flex flex-row items-center gap-2">
Index time window (days) <span class="block text-xs font-semibold text-emphasis">
<Tooltip> Index time window
Maximum age of items to include in the index. Jobs and logs older than this window will not <Tooltip>
be indexed and will be cleaned up from the index. Set to 0 to disable (index everything Cap the age of items the indexer keeps. Jobs and logs older than this window are not
within the retention period). indexed and are cleaned up from the index. Disable the cap to index everything within the
</Tooltip> retention period.
</label> </Tooltip>
<IntegerInput </span>
placeholder="7" <div class="ml-auto">
id="max_index_time_window_secs" <Toggle
{disabled} {disabled}
error={errors.max_index_time_window_secs ?? ''} checked={isTimeWindowCapped}
value={$values['indexer_settings'].max_index_time_window_secs != null on:change={(e) => setTimeWindowCapped(e.detail)}
? Math.round($values['indexer_settings'].max_index_time_window_secs / 86400) options={{ right: 'Cap by time window' }}
: undefined} />
oninput={(v) => { </div>
if (v == null) { </div>
const { max_index_time_window_secs: _, ...rest } = $values['indexer_settings'] {#if isTimeWindowCapped}
$values['indexer_settings'] = rest <IntegerInput
} else { placeholder="7"
$values['indexer_settings'] = { id="max_index_time_window_secs"
...$values['indexer_settings'], {disabled}
max_index_time_window_secs: v * 86400 error={errors.max_index_time_window_secs ?? ''}
value={$values['indexer_settings'].max_index_time_window_secs != null
? Math.round($values['indexer_settings'].max_index_time_window_secs / 86400)
: undefined}
oninput={(v) => {
if (v == null) {
const { max_index_time_window_secs: _, ...rest } = $values['indexer_settings']
$values['indexer_settings'] = rest
} else {
$values['indexer_settings'] = {
...$values['indexer_settings'],
max_index_time_window_secs: v * 86400
}
} }
} }}
}} />
/> <span class="text-2xs text-tertiary">days (leave blank to use the default of 7 days)</span>
<InputError error={errors.max_index_time_window_secs ?? ''} /> <InputError error={errors.max_index_time_window_secs ?? ''} />
{/if}
</div> </div>
<Label label="Indexer status"> <Label label="Indexer status">
{#snippet action()} {#snippet action()}