fix: only sync dirty files on page load, import server state first - #2
Merged
Merged
Conversation
Previously, when the NGXS storage plugin restored a hydrated backend from localStorage, syncBackends would PUT all cached file contents to the server before importing the server's current state. This caused externally-edited flag files to be silently overwritten with stale localStorage data on every page load. Now syncRemoteBackend only runs when there are user-edited (isDirty) files, and only those dirty files are synced. The server's state is always imported afterward, ensuring external edits are respected. This explains why incognito mode worked (no localStorage = no stale cache to sync) while normal browsing reverted flag edits. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The server was not handling SIGTERM, causing Docker to wait the full stop timeout (default 10s) before sending SIGKILL. Now axum::serve uses with_graceful_shutdown to listen for both SIGTERM and SIGINT, allowing the container to exit promptly on docker stop. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The docker-publish job was building linux/amd64,linux/arm64 via QEMU emulation on an x86 runner, causing 30+ minute Rust compilation times. Since all consumers run arm64 (macOS with OrbStack/Docker Desktop), switch to: - ubuntu-24.04-arm runner (native arm64, no emulation) - linux/arm64 platform only - Remove QEMU setup step (no longer needed) This should reduce publish time from ~30min to ~5min. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update all GitHub Actions to their latest major versions (Node 22 runtime) to eliminate Node 20 deprecation warnings. Remove unused stub structs in build.rs and suppress dead_code warning on AppState.config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GitHub Pages is not configured on this repo, so the docs-deploy job never ran. Remove it along with the OpenAPI schema extract/upload steps and docs screenshots upload that only served the docs build. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The azurite/azurite-init services require locally generated TLS certs that aren't in the repo, causing CI playwright tests to fail. These services already exist in docker-compose.azure.yaml for Azure-backed development. The default compose now only starts flagd-ui and flagd, which is all the e2e tests need. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
syncRemoteBackendnow only PUTs files that the user explicitly edited in the UI (isDirty: true)Problem
When the NGXS storage plugin restores a hydrated backend from
localStorage,syncBackendswas called withisHydrated: true. This triggeredsyncRemoteBackendwhich iterated over ALL cached files and PUT them to the server — even though they were stale (from a previous session). Only after that didimportRemoteBackendfetch the current server state.This caused flag files edited externally (e.g. via
sell/local/flagd/flags.flagd.json) to be silently overwritten every time the UI was loaded in a browser with cached state.Why incognito worked: No
localStorage→isHydratedstartsfalse→ skipssyncRemoteBackend→ goes straight to import.Changes
In
flag-file-store.state.ts:syncBackends: only callsyncRemoteBackendwhen there are dirty filessyncRemoteBackend: filter to only dirty files instead of syncing all files; remove the delete-remote-files-not-in-local logic (which could delete flags added externally)Test plan
🤖 Generated with Claude Code