@statezero/core 0.1.70 → 0.1.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/syncEngine/sync.d.ts +3 -0
- package/dist/syncEngine/sync.js +24 -32
- package/package.json +1 -1
|
@@ -22,6 +22,8 @@ export class SyncManager {
|
|
|
22
22
|
debounceMs: number;
|
|
23
23
|
maxWaitMs: number;
|
|
24
24
|
batchStartTime: number | null;
|
|
25
|
+
syncQueue: PQueue<import("p-queue/dist/priority-queue").default, import("p-queue").QueueAddOptions>;
|
|
26
|
+
withTimeout(promise: any, ms: any): Promise<any>;
|
|
25
27
|
/**
|
|
26
28
|
* Initialize event handlers for all event receivers
|
|
27
29
|
*/
|
|
@@ -41,4 +43,5 @@ export class SyncManager {
|
|
|
41
43
|
processMetrics(event: any): void;
|
|
42
44
|
processModels(event: any): void;
|
|
43
45
|
}
|
|
46
|
+
import PQueue from "p-queue";
|
|
44
47
|
export const syncManager: SyncManager;
|
package/dist/syncEngine/sync.js
CHANGED
|
@@ -8,6 +8,7 @@ import { metricRegistry, MetricRegistry } from "./registries/metricRegistry";
|
|
|
8
8
|
import { getModelClass, getConfig } from "../config";
|
|
9
9
|
import { isNil } from "lodash-es";
|
|
10
10
|
import { QuerysetStore } from "./stores/querysetStore";
|
|
11
|
+
import PQueue from "p-queue";
|
|
11
12
|
export class EventPayload {
|
|
12
13
|
constructor(data) {
|
|
13
14
|
this.event = data.event;
|
|
@@ -85,6 +86,25 @@ export class SyncManager {
|
|
|
85
86
|
this.debounceMs = 100; // Wait for rapid events to settle
|
|
86
87
|
this.maxWaitMs = 2000; // Maximum time to hold events
|
|
87
88
|
this.batchStartTime = null;
|
|
89
|
+
// SyncQueue
|
|
90
|
+
this.syncQueue = new PQueue({ concurrency: 3 });
|
|
91
|
+
}
|
|
92
|
+
withTimeout(promise, ms) {
|
|
93
|
+
// If no timeout specified, use 2x the periodic sync interval, or 30s as fallback
|
|
94
|
+
if (!ms) {
|
|
95
|
+
try {
|
|
96
|
+
const config = getConfig();
|
|
97
|
+
const intervalSeconds = config.periodicSyncIntervalSeconds;
|
|
98
|
+
ms = intervalSeconds ? intervalSeconds * 2000 : 30000; // 2x interval in ms, or 30s default
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
ms = 30000; // 30s fallback if no config
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return Promise.race([
|
|
105
|
+
promise,
|
|
106
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Sync timeout after ${ms}ms`)), ms)),
|
|
107
|
+
]);
|
|
88
108
|
}
|
|
89
109
|
/**
|
|
90
110
|
* Initialize event handlers for all event receivers
|
|
@@ -134,13 +154,13 @@ export class SyncManager {
|
|
|
134
154
|
// Only sync if this store is actually being followed
|
|
135
155
|
const isFollowed = this.isStoreFollowed(querysetRegistry, semanticKey);
|
|
136
156
|
if (this.followAllQuerysets || isFollowed) {
|
|
137
|
-
store.sync();
|
|
157
|
+
this.syncQueue.add(() => this.withTimeout(store.sync()));
|
|
138
158
|
syncedCount++;
|
|
139
159
|
}
|
|
140
160
|
}
|
|
141
161
|
}
|
|
142
162
|
if (syncedCount > 0) {
|
|
143
|
-
console.log(`[SyncManager] Periodic sync: ${syncedCount} stores
|
|
163
|
+
console.log(`[SyncManager] Periodic sync: ${syncedCount} stores pushed to the sync queue`);
|
|
144
164
|
}
|
|
145
165
|
}
|
|
146
166
|
isStoreFollowed(registry, semanticKey) {
|
|
@@ -267,10 +287,7 @@ export class SyncManager {
|
|
|
267
287
|
// Sync all relevant stores for this model
|
|
268
288
|
console.log(`[SyncManager] Syncing ${storesToSync.length} queryset stores for ${representativeEvent.model}`);
|
|
269
289
|
storesToSync.forEach((store) => {
|
|
270
|
-
|
|
271
|
-
store.sync().catch((error) => {
|
|
272
|
-
console.error(`[SyncManager] Failed to sync queryset store:`, error);
|
|
273
|
-
});
|
|
290
|
+
this.syncQueue.add(() => this.withTimeout(store.sync()));
|
|
274
291
|
});
|
|
275
292
|
}
|
|
276
293
|
processMetrics(event) {
|
|
@@ -293,32 +310,7 @@ export class SyncManager {
|
|
|
293
310
|
}
|
|
294
311
|
}
|
|
295
312
|
processModels(event) {
|
|
296
|
-
|
|
297
|
-
if (!registry)
|
|
298
|
-
return;
|
|
299
|
-
// Get the model class for this event
|
|
300
|
-
const modelClass = event.modelClass;
|
|
301
|
-
if (!modelClass)
|
|
302
|
-
return;
|
|
303
|
-
// Get the model store for this model class
|
|
304
|
-
const modelStore = registry.getStore(modelClass);
|
|
305
|
-
if (!modelStore)
|
|
306
|
-
return;
|
|
307
|
-
// Event instances are just PKs - find which ones we have locally
|
|
308
|
-
const eventPks = event.instances || [];
|
|
309
|
-
// Get all currently rendered instances (includes ground truth + operations)
|
|
310
|
-
const renderedInstances = modelStore.render();
|
|
311
|
-
const localPks = new Set(renderedInstances.map((instance) => instance[modelClass.primaryKeyField]));
|
|
312
|
-
const pksToSync = eventPks.filter((pk) => localPks.has(pk));
|
|
313
|
-
if (pksToSync.length === 0) {
|
|
314
|
-
console.log(`[SyncManager] No locally cached instances to sync for ${event.model}`);
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
// Sync only the PKs that are both in the event and locally cached
|
|
318
|
-
console.log(`[SyncManager] Syncing ${pksToSync.length} model instances for ${event.model}`);
|
|
319
|
-
modelStore.sync(pksToSync).catch((error) => {
|
|
320
|
-
console.error(`[SyncManager] Failed to sync model store for ${event.model}:`, error);
|
|
321
|
-
});
|
|
313
|
+
return;
|
|
322
314
|
}
|
|
323
315
|
}
|
|
324
316
|
const syncManager = new SyncManager();
|
package/package.json
CHANGED