bulltrackers-module 1.0.770 → 1.0.772
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/functions/computation-system-v2/computations/GlobalAumPerAsset30D.js +11 -13
- package/functions/computation-system-v2/computations/PIDailyAssetAUM.js +17 -19
- package/functions/computation-system-v2/computations/PiFeatureVectors.js +44 -90
- package/functions/computation-system-v2/computations/PiRecommender.js +155 -226
- package/functions/computation-system-v2/computations/PopularInvestorProfileMetrics.js +20 -20
- package/functions/computation-system-v2/computations/SectorCorrelations.js +228 -0
- package/functions/computation-system-v2/computations/SignedInUserMirrorHistory.js +15 -32
- package/functions/computation-system-v2/computations/SignedInUserProfileMetrics.js +31 -31
- package/functions/computation-system-v2/framework/core/RunAnalyzer.js +3 -2
- package/functions/computation-system-v2/framework/data/DataFetcher.js +1 -1
- package/functions/computation-system-v2/framework/storage/StateRepository.js +13 -11
- package/functions/computation-system-v2/handlers/scheduler.js +43 -19
- package/package.json +1 -1
- package/functions/computation-system-v2/docs/Agents.MD +0 -964
|
@@ -168,46 +168,67 @@ async function runWatchdog(req, res) {
|
|
|
168
168
|
return res.status(500).json({ error: error.message });
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
|
-
|
|
172
171
|
// =============================================================================
|
|
173
172
|
// ACTIVE GARBAGE COLLECTION LOGIC
|
|
174
173
|
// =============================================================================
|
|
175
174
|
|
|
176
175
|
async function cleanupOrphanedTasks() {
|
|
177
176
|
const parent = getQueuePath();
|
|
178
|
-
|
|
177
|
+
|
|
178
|
+
// Create a map of { kebabName: activeHash } for O(1) lookups
|
|
179
|
+
const activeComputations = new Map(
|
|
180
|
+
manifest.map(m => [toKebab(m.originalName), m.hash])
|
|
181
|
+
);
|
|
182
|
+
|
|
179
183
|
const limit = pLimit(CLOUD_TASKS_CONCURRENCY);
|
|
180
184
|
let deletedCount = 0;
|
|
181
185
|
|
|
182
186
|
try {
|
|
183
|
-
// Iterate over ALL tasks in the queue
|
|
184
|
-
// Note: listTasksAsync handles pagination automatically
|
|
185
187
|
const tasksToDelete = [];
|
|
186
188
|
|
|
187
|
-
|
|
189
|
+
// Note: listTasksAsync handles pagination, but if you have thousands of tasks,
|
|
190
|
+
// you might eventually need to handle page tokens explicitly if the library version is old.
|
|
191
|
+
for await (const task of tasksClient.listTasksAsync({
|
|
192
|
+
parent,
|
|
193
|
+
responseView: 'BASIC',
|
|
194
|
+
pageSize: 1000 // Increase page size to capture more per request
|
|
195
|
+
})){
|
|
188
196
|
const taskNameFull = task.name;
|
|
189
|
-
const taskNameShort = taskNameFull.split('/').pop();
|
|
197
|
+
const taskNameShort = taskNameFull.split('/').pop();
|
|
190
198
|
|
|
191
|
-
// 1.
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
// Hash is 8 chars (or more)
|
|
195
|
-
const match = taskNameShort.match(/^(?:root|recovery)-(.+)-\d{4}-\d{2}-\d{2}-/);
|
|
199
|
+
// 1. Handle ROOT Tasks: root-{kebabName}-{date}-{hash}
|
|
200
|
+
// We capture the name AND the hash at the end
|
|
201
|
+
const rootMatch = taskNameShort.match(/^root-(.+)-\d{4}-\d{2}-\d{2}-(.+)$/);
|
|
196
202
|
|
|
197
|
-
if (
|
|
203
|
+
if (rootMatch) {
|
|
204
|
+
const [_, kebabName, taskHash] = rootMatch;
|
|
205
|
+
const activeHash = activeComputations.get(kebabName);
|
|
198
206
|
|
|
199
|
-
|
|
207
|
+
// DELETE IF:
|
|
208
|
+
// A) Computation removed from manifest (!activeHash)
|
|
209
|
+
// B) Hash mismatch (Old deployment/Stale) (activeHash !== taskHash)
|
|
210
|
+
if (!activeHash || activeHash !== taskHash) {
|
|
211
|
+
tasksToDelete.push(taskNameFull);
|
|
212
|
+
}
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
200
215
|
|
|
201
|
-
// 2.
|
|
202
|
-
if
|
|
203
|
-
|
|
204
|
-
|
|
216
|
+
// 2. Handle RECOVERY Tasks: recovery-{kebabName}-{date}-{timestamp}
|
|
217
|
+
// We only delete these if the computation is completely gone.
|
|
218
|
+
// (Timestamps won't match a config hash, so we just check existence)
|
|
219
|
+
const recoveryMatch = taskNameShort.match(/^recovery-(.+)-\d{4}-\d{2}-\d{2}-/);
|
|
220
|
+
|
|
221
|
+
if (recoveryMatch) {
|
|
222
|
+
const [_, kebabName] = recoveryMatch;
|
|
223
|
+
if (!activeComputations.has(kebabName)) {
|
|
224
|
+
tasksToDelete.push(taskNameFull);
|
|
225
|
+
}
|
|
205
226
|
}
|
|
206
227
|
}
|
|
207
228
|
|
|
208
229
|
if (tasksToDelete.length === 0) return 0;
|
|
209
230
|
|
|
210
|
-
console.log(`[Planner] 🗑️ Found ${tasksToDelete.length} orphaned tasks. Deleting...`);
|
|
231
|
+
console.log(`[Planner] 🗑️ Found ${tasksToDelete.length} stale/orphaned tasks. Deleting...`);
|
|
211
232
|
|
|
212
233
|
// 3. Delete in parallel
|
|
213
234
|
await Promise.all(tasksToDelete.map(name => limit(async () => {
|
|
@@ -215,7 +236,10 @@ async function cleanupOrphanedTasks() {
|
|
|
215
236
|
await tasksClient.deleteTask({ name });
|
|
216
237
|
deletedCount++;
|
|
217
238
|
} catch (e) {
|
|
218
|
-
|
|
239
|
+
// Ignore "NOT_FOUND" errors in case of race conditions
|
|
240
|
+
if (e.code !== 5) {
|
|
241
|
+
console.warn(`[Planner] Failed to delete ${name}: ${e.message}`);
|
|
242
|
+
}
|
|
219
243
|
}
|
|
220
244
|
})));
|
|
221
245
|
|