bulltrackers-module 1.0.311 → 1.0.312

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.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * FILENAME: computation-system/helpers/computation_dispatcher.js
3
3
  * PURPOSE: Sequential Cursor-Based Dispatcher with Hyper-Verbose Telemetry.
4
- * FIX: Added dispatchId generation and triggerReason mapping.
4
+ * FIX: Added dispatchId, triggerReason, and detailed logging requirements.
5
5
  */
6
6
 
7
7
  const { getExpectedDateStrings, getEarliestDataDates, normalizeName, DEFINITIVE_EARLIEST_DATES } = require('../utils/utils.js');
@@ -9,7 +9,7 @@ const { groupByPass, analyzeDateExecution } = require('../WorkflowOrchestrator.j
9
9
  const { PubSubUtils } = require('../../core/utils/pubsub_utils');
10
10
  const { fetchComputationStatus } = require('../persistence/StatusRepository');
11
11
  const { checkRootDataAvailability } = require('../data/AvailabilityChecker');
12
- const crypto = require('crypto'); // [NEW] Required for dispatchId
12
+ const crypto = require('crypto');
13
13
 
14
14
  const OOM_THRESHOLD_MB = 1500;
15
15
  const SECONDS_PER_CALC_MARGIN = 25;
@@ -43,14 +43,12 @@ async function dispatchComputationPass(config, dependencies, computationManifest
43
43
  const targetCursorN = parseInt(reqBody.cursorIndex || 1);
44
44
  const dateLimitStr = reqBody.date || config.date || "2025-01-01";
45
45
 
46
- logger.log('INFO', `[Dispatcher] 🚀 STARTING DISPATCH: Pass ${passToRun}, Cursor ${targetCursorN}, Limit ${dateLimitStr}`);
47
-
48
46
  const manifestMap = new Map(computationManifest.map(c => [normalizeName(c.name), c]));
49
47
  const passes = groupByPass(computationManifest);
50
48
  const calcsInThisPass = passes[passToRun] || [];
51
49
 
52
50
  if (!calcsInThisPass.length) {
53
- logger.log('WARN', `[Dispatcher] 🛑 No calculations found for Pass ${passToRun}. Moving to next pass.`);
51
+ logger.log('WARN', `[Dispatcher] 🛑 No calculations found for Pass ${passToRun}.`);
54
52
  return { status: 'MOVE_TO_NEXT_PASS', dispatched: 0 };
55
53
  }
56
54
 
@@ -62,6 +60,7 @@ async function dispatchComputationPass(config, dependencies, computationManifest
62
60
  return { status: 'MOVE_TO_NEXT_PASS', dispatched: 0 };
63
61
  }
64
62
 
63
+ // 1. Identify all "Dirty" dates (dates that actually have work to do)
65
64
  const dirtyDates = [];
66
65
  for (const d of allDates) {
67
66
  const dailyStatus = await fetchComputationStatus(d, config, dependencies);
@@ -82,10 +81,10 @@ async function dispatchComputationPass(config, dependencies, computationManifest
82
81
  let isReroute = false;
83
82
  let isSweep = false;
84
83
 
84
+ // Logic for Reroutes (OOM handling)
85
85
  if (targetCursorN > 1 && (targetCursorN - 2) < dirtyDates.length) {
86
86
  const prevEntry = dirtyDates[targetCursorN - 2];
87
87
  const reroutes = await getHighMemReroutes(db, prevEntry.date, passToRun, prevEntry.tasks);
88
-
89
88
  if (reroutes.length > 0) {
90
89
  selectedDate = prevEntry.date;
91
90
  selectedTasks = reroutes;
@@ -93,6 +92,7 @@ async function dispatchComputationPass(config, dependencies, computationManifest
93
92
  }
94
93
  }
95
94
 
95
+ // Logic for standard cursor progression
96
96
  if (!selectedDate) {
97
97
  if (targetCursorN <= dirtyDates.length) {
98
98
  const entry = dirtyDates[targetCursorN - 1];
@@ -106,11 +106,27 @@ async function dispatchComputationPass(config, dependencies, computationManifest
106
106
  }
107
107
 
108
108
  if (!selectedDate) {
109
+ logger.log('INFO', `[Dispatcher] 🏁 Pass ${passToRun} is fully satiated. No work remaining.`);
109
110
  return { status: 'MOVE_TO_NEXT_PASS', dispatched: 0, etaSeconds: 0 };
110
111
  }
111
112
 
112
- // [FIX] Generate unique Dispatch ID for this wave and map triggerReason
113
+ // 2. Prepare Payload and Telemetry
113
114
  const currentDispatchId = crypto.randomUUID();
115
+ const etaSeconds = Math.max(20, selectedTasks.length * SECONDS_PER_CALC_MARGIN);
116
+ const remainingDatesCount = Math.max(0, dirtyDates.length - targetCursorN);
117
+
118
+ // requirement: condense computations into a log payload
119
+ const computationNames = selectedTasks.map(t => t.name);
120
+
121
+ logger.log('INFO', `[Dispatcher] ✅ Dispatching ${selectedTasks.length} tasks for ${selectedDate}. ETA: ${etaSeconds}s.`, {
122
+ date: selectedDate,
123
+ pass: passToRun,
124
+ dispatchedCount: selectedTasks.length,
125
+ remainingCursorDates: remainingDatesCount,
126
+ etaSeconds: etaSeconds,
127
+ dispatchId: currentDispatchId,
128
+ tasks: computationNames // Condensed into JSON payload
129
+ });
114
130
 
115
131
  const mapToTaskPayload = (t) => ({
116
132
  ...t,
@@ -118,8 +134,8 @@ async function dispatchComputationPass(config, dependencies, computationManifest
118
134
  computation: t.name,
119
135
  date: selectedDate,
120
136
  pass: passToRun,
121
- dispatchId: currentDispatchId, // [NEW] Added for Worker Audit Lease
122
- triggerReason: t.reason // [NEW] Map 'reason' from Orchestrator to 'triggerReason'
137
+ dispatchId: currentDispatchId,
138
+ triggerReason: t.reason
123
139
  });
124
140
 
125
141
  const standardTasks = selectedTasks.filter(t => t.resources !== 'high-mem').map(mapToTaskPayload);
@@ -142,14 +158,13 @@ async function dispatchComputationPass(config, dependencies, computationManifest
142
158
  }
143
159
  await Promise.all(pubPromises);
144
160
 
145
- const etaSeconds = Math.max(20, selectedTasks.length * SECONDS_PER_CALC_MARGIN);
146
-
147
161
  return {
148
162
  status : isSweep ? 'RECOVERY' : 'CONTINUE_PASS',
149
163
  dateProcessed : selectedDate,
150
164
  dispatched : selectedTasks.length,
151
165
  n_cursor_ignored: isReroute,
152
- etaSeconds : etaSeconds
166
+ etaSeconds : etaSeconds,
167
+ remainingDates : remainingDatesCount // For Workflow consumption
153
168
  };
154
169
  }
155
170
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.311",
3
+ "version": "1.0.312",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [