Skip to content

feat: Allow resource syncs to self update#1492

Open
scolastico wants to merge 1 commit into
moghtech:mainfrom
scolastico:feat/allow-self-updating-syncs
Open

feat: Allow resource syncs to self update#1492
scolastico wants to merge 1 commit into
moghtech:mainfrom
scolastico:feat/allow-self-updating-syncs

Conversation

@scolastico

@scolastico scolastico commented Jun 23, 2026

Copy link
Copy Markdown

Let resource syncs sync themselves

Fixes #676

What this does

A resource sync can declare itself among the resources it manages. Before
this change, running such a sync - when its own config had changed - always
failed with ResourceSync busy and left the sync stuck in Pending with
no clear recovery path. The only workarounds were removing the sync's own
declaration from the TOML, or hand-editing the UI config to match git exactly.

This PR makes a sync able to apply changes to itself during its own run, adds
an opt-in to immediately re-run when a sync changes its own scope, and turns
the "a sync would delete itself" case into an explicit hard error instead of a
confusing busy failure.

Why it happened

When a sync runs, it takes its own action-state lock (syncing = true) for the
entire run. Applying the sync's own changes goes through
resource::update::<ResourceSync>, which starts with a busy check:

if T::busy(&resource.id).await? {
  return Err(anyhow!("{} busy", T::resource_type()));
}

Because the sync is the thing holding the lock, this check always trips for the
sync's own entry - so it could never converge.

How it works

1. Apply self-updates, bypassing the busy check

  • resource::update was split into update (unchanged, busy-checked) and a new
    update_ignore_busy, sharing a private update_inner(..., check_busy: bool).
    No other call sites change.
  • A new execute_self_sync_updates pulls the sync's own entry out of the
    ResourceSync deltas and applies the config update directly via
    update_ignore_busy. This is safe: it runs sequentially as part of the
    in-progress sync, not concurrently. (Tag/description/template meta updates
    already worked, since update_meta has no busy check.)

2. Optional re-run when a sync changes its own scope (rerun_on_self_change)

A run reconciles against the config that was active when the run started. If a
sync changes its own config mid-run (e.g. a new resource_path), that new scope
only takes effect on the next run - the end-of-run RefreshResourceSyncPending
correctly recomputes pending against the new config, so the sync simply shows
Pending again (it does not get falsely marked "in sync").

New opt-in config field rerun_on_self_change (default false): when the sync
successfully changed its own config during a pass, run one more pass immediately
to apply the new scope, instead of waiting for an external trigger.

To support this, RunSync::resolve was refactored so the per-pass reconciliation
lives in execute_sync_pass(...), driven by a small loop hard-capped at
MAX_SYNC_PASSES = 2. The cap guarantees termination even if a sync's TOML never
quite diff-matches itself; if it's still Pending after the second pass it stays
Pending.

3. A sync can never delete itself (hard fail)

If delete/managed mode is enabled and the running sync is not declared in
its own resource files, it would otherwise be marked for deletion. This now
hard-fails the run up front - before any resource is mutated - with a clear
message, rather than silently skipping the deletion or failing as "busy":

Sync '' is configured to delete itself: it is not declared in its own
resource files while delete/managed mode is enabled. Declare it in the
resource files, or remove it manually / disable delete mode.

Failing early (right after deltas are computed) avoids a half-applied sync.

Behavior summary

Scenario Before After
Sync changes its own config ResourceSync busy, stuck Pending Applied during the run
rerun_on_self_change off (default) n/a First run applies the self change; new scope shows as Pending
rerun_on_self_change on n/a Runs once more automatically to apply the new scope
Sync would delete itself (delete/managed, not self-declared) ResourceSync busy Hard error before any mutation

Changes

  • bin/core/src/resource/mod.rs - split update into update /
    update_ignore_busy / update_inner(check_busy).
  • bin/core/src/sync/execute.rs - execute_self_sync_updates (applies the
    sync's own update, bypassing busy; returns whether config changed).
  • bin/core/src/api/execute/sync.rs - extracted execute_sync_pass, added the
    capped re-run loop and the early self-delete hard fail.
  • client/core/rs/src/entities/sync.rs - new rerun_on_self_change config
    field (default false).
  • client/core/ts/src/types.ts, ui/public/client/types.d.ts - generated TS
    type for the new field.
  • ui/src/resources/sync/config.tsx - "Re-run On Self Change" toggle.
  • docsite/docs/automate/sync-resources.md - documents self-managing syncs, the
    new option, and the self-delete hard fail.

Testing

  • cargo check -p komodo_core and -p komodo_client pass with no warnings.
  • Tested against local dev instance, see screenshots below.

Screenshots

image image

@scolastico scolastico changed the title [FEATURE] Allow resource syncs to self update feat: Allow resource syncs to self update Jun 23, 2026
@scolastico

Copy link
Copy Markdown
Author

Even tho i tested this, i would recommend more indepth testing. Im currently trying to build a beta release in my repo, which i would test in a prod env. Tho as first tests seem successfull i update this pr from draft to review ready.

@scolastico scolastico marked this pull request as ready for review June 24, 2026 09:27
@scolastico

Copy link
Copy Markdown
Author

Created a ci for unstable releases of my changes: https://github.com/scolastico/komodo/tree/unstable-release

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Improve resource sync self handling

1 participant