@mindline/sync 1.0.110 → 1.0.111

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindline/sync",
3
- "version": "1.0.110",
3
+ "version": "1.0.111",
4
4
  "description": "sync is a node.js package encapsulating JavaScript classes required for configuring Mindline sync service.",
5
5
  "main": "dist/sync.es.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -929,13 +929,6 @@ export class BatchArray {
929
929
  private pollAuthorizedUser: User | null = null;
930
930
  private pollBatchIdArray: Array<any> = [];
931
931
 
932
- // Last known backend queues (strongest completion signal)
933
- private lastQueues: { main: number | null; writer: number | null; deferred: number | null } = {
934
- main: null,
935
- writer: null,
936
- deferred: null
937
- };
938
- private hasQueueInfo: boolean = false;
939
932
 
940
933
  // Store UI callbacks so we can update the UI from poll/completion events.
941
934
  private setIdleText: ((idleText: string) => void) | null = null;
@@ -1049,10 +1042,6 @@ export class BatchArray {
1049
1042
  // Save callback so completion/polling can update the idle text too.
1050
1043
  this.setIdleText = setIdleText;
1051
1044
 
1052
- // IMPORTANT: reset completion signals between sync runs.
1053
- // Otherwise a previous run that ended with queues=0 could make the next run immediately "Complete".
1054
- this.hasQueueInfo = false;
1055
- this.lastQueues = { main: null, writer: null, deferred: null };
1056
1045
 
1057
1046
  this.pb_startTS = Date.now();
1058
1047
  this.pb_progress = 0;
@@ -1061,35 +1050,14 @@ export class BatchArray {
1061
1050
  setSyncProgress(this.pb_progress);
1062
1051
  setIdleText("Starting sync...");
1063
1052
  this.pb_timer = setInterval(() => {
1064
- // If backend indicates completion (prefer queue-empty when available), stop the timer
1053
+ // Completion check is now handled by the SignalR handler via isSyncCompleted()
1054
+ // This timer only increments elapsed time; actual completion logic lives in the handler.
1065
1055
  console.log("this.tenantNodes", this.tenantNodes)
1066
- let isCompletedOrNothingToSync = this.tenantNodes.every((tn: TenantNode) =>
1067
- tn.nothingtosync || tn.targets.every((ta) => ta.status === "complete" || ta.status === "failed")
1068
- );
1069
1056
 
1070
- const queuesEmpty = this.hasQueueInfo &&
1071
- this.lastQueues.main === 0 &&
1072
- this.lastQueues.writer === 0 &&
1073
- this.lastQueues.deferred === 0;
1057
+ this.pb_total = this.pb_total + 1;
1058
+ this.pb_idle = this.pb_idle + 1;
1074
1059
 
1075
- // If we have queue info, trust it for completion. Otherwise fall back to node terminal states.
1076
- const isCompleted = queuesEmpty || (!this.hasQueueInfo && isCompletedOrNothingToSync);
1077
-
1078
- if (isCompleted) {
1079
- clearInterval(this.pb_timer!);
1080
- this.pb_timer = null;
1081
- this.pb_progress = 100;
1082
- setSyncProgress(this.pb_progress);
1083
- setIdleText(`Complete.`);
1084
- this.stopPolling();
1085
- this.clearStoredBatchIds();
1086
- }
1087
- else {
1088
- this.pb_total = this.pb_total + 1;
1089
- this.pb_idle = this.pb_idle + 1;
1090
-
1091
- setIdleText(`${this.pb_total} seconds elapsed. Last update ${this.pb_idle} seconds ago.`);
1092
- }
1060
+ setIdleText(`${this.pb_total} seconds elapsed. Last update ${this.pb_idle} seconds ago.`);
1093
1061
  }, 1000);
1094
1062
  this.milestoneArray.start(setMilestones);
1095
1063
  }
@@ -1202,9 +1170,6 @@ export class BatchArray {
1202
1170
  bClearLocalStorage = bClearLocalStorage;
1203
1171
  message = message;
1204
1172
 
1205
- // Starting a new SignalR session for a (potentially new) run: reset queue-based completion signals.
1206
- this.hasQueueInfo = false;
1207
- this.lastQueues = { main: null, writer: null, deferred: null };
1208
1173
 
1209
1174
  // we have just completed a successful POST to startSync
1210
1175
  this.milestoneArray.post(setMilestones);
@@ -1235,10 +1200,6 @@ export class BatchArray {
1235
1200
  // does this tenantnode/batch have nothing to sync?
1236
1201
  let bTotalCountZero: boolean = false;
1237
1202
  let bCurrentCountZero: boolean = false;
1238
- // queue stats (better completion signal than only written/total)
1239
- let totalInMainQueue: number | null = null;
1240
- let totalInWriterQueue: number | null = null;
1241
- let totalInDeferredQueue: number | null = null;
1242
1203
  for (let j = 0; j < statskeys.length; j++) {
1243
1204
  let bTotalCount = statskeys[j].endsWith("TotalCount");
1244
1205
  let bCurrentCount = statskeys[j].endsWith("CurrentCount");
@@ -1292,16 +1253,6 @@ export class BatchArray {
1292
1253
  }
1293
1254
  tenantNode.nothingtosync = bTotalCountZero && bCurrentCountZero;
1294
1255
 
1295
- // queue stats are global for the batch
1296
- if (statskeys[j] === "TotalInMainQueue") {
1297
- totalInMainQueue = Number(statsvalues[j]);
1298
- }
1299
- if (statskeys[j] === "TotalInWriterQueue") {
1300
- totalInWriterQueue = Number(statsvalues[j]);
1301
- }
1302
- if (statskeys[j] === "TotalInDeferredQueue") {
1303
- totalInDeferredQueue = Number(statsvalues[j]);
1304
- }
1305
1256
 
1306
1257
  if (statskeys[j].startsWith("Writer")) {
1307
1258
  // parse tid from Writer key
@@ -1379,23 +1330,17 @@ export class BatchArray {
1379
1330
  readerExcluded += sourceTenantNode.excluded;
1380
1331
  });
1381
1332
 
1382
- // If queue stats are available, they are a stronger indicator of write completion.
1383
- // When all queues are empty, the backend has finished processing this batch and may stop emitting updates.
1384
- if (totalInMainQueue != null) this.lastQueues.main = totalInMainQueue;
1385
- if (totalInWriterQueue != null) this.lastQueues.writer = totalInWriterQueue;
1386
- if (totalInDeferredQueue != null) this.lastQueues.deferred = totalInDeferredQueue;
1387
- this.hasQueueInfo = this.lastQueues.main != null && this.lastQueues.writer != null && this.lastQueues.deferred != null;
1388
-
1389
- const queuesEmpty = this.hasQueueInfo &&
1390
- this.lastQueues.main === 0 &&
1391
- this.lastQueues.writer === 0 &&
1392
- this.lastQueues.deferred === 0;
1333
+ // New completion condition: sync is complete when:
1334
+ // (Reader/TotalCount - Reader/ExtCount) === (Writer/CurrentCount + Writer/DeferredCount)
1335
+ // This means all users that should be written (total minus excluded) have been processed.
1336
+ const usersToSync = readerTotal - readerExcluded;
1337
+ const usersProcessed = writerCurrent + writerDeferred;
1338
+ const isSyncCompleted = usersToSync > 0 && usersToSync === usersProcessed;
1393
1339
 
1394
- if (queuesEmpty) {
1340
+ if (isSyncCompleted) {
1395
1341
  bWritingComplete = true;
1396
1342
 
1397
- // Ensure the UI can reach a terminal state even if writer CurrentCount never reaches TotalCount.
1398
- // We trust the backend queues more than client-side totals in this scenario.
1343
+ // Mark all nodes as complete since sync condition is satisfied.
1399
1344
  this.tenantNodes.forEach((src) => {
1400
1345
  src.targets.forEach((t) => {
1401
1346
  if (t.status !== "failed") t.status = "complete";
@@ -1450,8 +1395,8 @@ export class BatchArray {
1450
1395
  setRefreshDeltaTrigger(config!.workspaceId);
1451
1396
  }
1452
1397
  // with that out of the way, is writing complete?
1453
- // Only allow terminal completion when backend queues are empty (if we have queue info).
1454
- if (bWritingComplete && (queuesEmpty || !this.hasQueueInfo)) {
1398
+ // Completion is determined by the new formula: usersToSync === usersProcessed
1399
+ if (bWritingComplete && isSyncCompleted) {
1455
1400
  this.milestoneArray.write(setMilestones);
1456
1401
  this.stopPolling();
1457
1402
  setConfigSyncResult("sync complete");