fix(FN-4907): invalidate stale settings caches on sync and provider writes
Fusion-Task-Id: FN-4907 Fusion-Task-Lineage: e84d5357-0719-4cc7-ab3f-f665ac83b218
This commit is contained in:
committed by
gsxdsm
parent
f6d6f0f4c0
commit
4416de159c
@@ -366,6 +366,8 @@ export async function runDaemon(opts: DaemonOptions = {}) {
|
||||
peerExchangeService = new PeerExchangeService(sharedCentralCore);
|
||||
try {
|
||||
peerExchangeService.start();
|
||||
const globalSettings = await store.getGlobalSettingsStore().getSettings();
|
||||
peerExchangeService.updateGlobalSettings(globalSettings);
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
console.warn(`[daemon] Failed to start peer exchange service: ${message}`);
|
||||
@@ -439,6 +441,13 @@ export async function runDaemon(opts: DaemonOptions = {}) {
|
||||
|
||||
const store = primaryEngine.getTaskStore();
|
||||
|
||||
store.on("settings:updated", () => {
|
||||
if (!peerExchangeService) return;
|
||||
void store.getGlobalSettingsStore().getSettings().then((globalSettings) => {
|
||||
peerExchangeService?.updateGlobalSettings(globalSettings);
|
||||
}).catch(() => undefined);
|
||||
});
|
||||
|
||||
await store.watch();
|
||||
|
||||
// Set up database health check for diagnostics
|
||||
|
||||
@@ -1406,6 +1406,11 @@ export async function runDashboard(port: number, opts: { paused?: boolean; dev?:
|
||||
});
|
||||
|
||||
registerHandler(store, "settings:updated", ({ settings, previous }) => {
|
||||
if (peerExchangeService) {
|
||||
void store.getGlobalSettingsStore().getSettings().then((globalSettings) => {
|
||||
peerExchangeService?.updateGlobalSettings(globalSettings);
|
||||
}).catch(() => undefined);
|
||||
}
|
||||
const currentProviders = settings.customProviders;
|
||||
const previousProviders = previous.customProviders;
|
||||
if (JSON.stringify(currentProviders ?? []) === JSON.stringify(previousProviders ?? [])) {
|
||||
@@ -1549,6 +1554,8 @@ export async function runDashboard(port: number, opts: { paused?: boolean; dev?:
|
||||
peerExchangeService = new PeerExchangeService(centralCoreForEngine);
|
||||
try {
|
||||
peerExchangeService.start();
|
||||
const globalSettings = await store.getGlobalSettingsStore().getSettings();
|
||||
peerExchangeService.updateGlobalSettings(globalSettings);
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
logSink.warn(`Failed to start peer exchange service: ${message}`, "dashboard");
|
||||
@@ -1764,6 +1771,8 @@ export async function runDashboard(port: number, opts: { paused?: boolean; dev?:
|
||||
|
||||
peerExchangeService = new PeerExchangeService(centralCoreForMesh);
|
||||
peerExchangeService.start();
|
||||
const globalSettings = await store.getGlobalSettingsStore().getSettings();
|
||||
peerExchangeService.updateGlobalSettings(globalSettings);
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
logSink.warn(`Failed to initialize mesh networking: ${message}`, "dashboard");
|
||||
|
||||
@@ -4,6 +4,7 @@ import net from "node:net";
|
||||
import type { CustomProvider } from "@fusion/core";
|
||||
import { ApiError, badRequest, notFound } from "../api-error.js";
|
||||
import type { ApiRouteRegistrar } from "./types.js";
|
||||
import { invalidateAllGlobalSettingsCaches } from "../project-store-resolver.js";
|
||||
|
||||
/**
|
||||
* Masks an API key for safe display, showing only the first 3 and last 4 characters.
|
||||
@@ -459,6 +460,7 @@ export const registerCustomProviderRoutes: ApiRouteRegistrar = (ctx) => {
|
||||
const settings = await store.getGlobalSettingsStore().getSettings();
|
||||
const providers = settings.customProviders ?? [];
|
||||
await store.updateGlobalSettings({ customProviders: [...providers, provider] });
|
||||
invalidateAllGlobalSettingsCaches();
|
||||
|
||||
res.status(201).json(sanitizeProvider(provider));
|
||||
} catch (err: unknown) {
|
||||
@@ -497,6 +499,7 @@ export const registerCustomProviderRoutes: ApiRouteRegistrar = (ctx) => {
|
||||
const nextProviders = [...providers];
|
||||
nextProviders[targetIndex] = updatedProvider;
|
||||
await store.updateGlobalSettings({ customProviders: nextProviders });
|
||||
invalidateAllGlobalSettingsCaches();
|
||||
|
||||
res.json(sanitizeProvider(updatedProvider));
|
||||
} catch (err: unknown) {
|
||||
@@ -528,6 +531,7 @@ export const registerCustomProviderRoutes: ApiRouteRegistrar = (ctx) => {
|
||||
|
||||
const nextProviders = providers.filter((provider) => provider.id !== providerId);
|
||||
await store.updateGlobalSettings({ customProviders: nextProviders });
|
||||
invalidateAllGlobalSettingsCaches();
|
||||
res.json({ success: true });
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof ApiError) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ApiError, badRequest } from "../api-error.js";
|
||||
import { invalidateAllGlobalSettingsCaches } from "../project-store-resolver.js";
|
||||
import { getFusionAuthPath } from "../auth-paths.js";
|
||||
import { readStoredAuthProvidersFromDisk, toProviderAuthEntries } from "./register-settings-sync-helpers.js";
|
||||
import type { ApiRouteRegistrar } from "./types.js";
|
||||
@@ -64,6 +65,20 @@ export const registerSettingsSyncInboundRoutes: ApiRouteRegistrar = (ctx) => {
|
||||
// Apply remote settings
|
||||
const result = await central.applyRemoteSettings(payload);
|
||||
|
||||
// Apply inbound global settings through TaskStore so process-local caches
|
||||
// and settings listeners receive consistent updates.
|
||||
if (result.success && payload.global && typeof payload.global === "object") {
|
||||
const localGlobal = await store.getGlobalSettingsStore().getSettings() as Record<string, unknown>;
|
||||
const globalPatch = Object.fromEntries(
|
||||
Object.entries(payload.global as Record<string, unknown>)
|
||||
.filter(([key, value]) => value !== undefined && localGlobal[key] === undefined),
|
||||
);
|
||||
if (Object.keys(globalPatch).length > 0) {
|
||||
await store.updateGlobalSettings(globalPatch);
|
||||
invalidateAllGlobalSettingsCaches();
|
||||
}
|
||||
}
|
||||
|
||||
// Build applied/skipped field lists
|
||||
const appliedFields = [
|
||||
...Object.keys(payload.global || {}),
|
||||
|
||||
Reference in New Issue
Block a user