bulltrackers-module 1.0.120 → 1.0.122

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,6 +1,11 @@
1
1
  /**
2
2
  * @fileoverview Sub-pipe for dispatching tasks.
3
3
  * REFACTORED: Now stateless and receives dependencies.
4
+ *
5
+ * --- MODIFICATION ---
6
+ * This file has been modified to publish tasks in batches
7
+ * within a single Pub/Sub message, rather than one message per task.
8
+ * This enables the Task Engine to process users in a stateful batch.
4
9
  */
5
10
 
6
11
  const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
@@ -23,12 +28,21 @@ async function dispatchTasksInBatches(tasks, dependencies, config) {
23
28
  logger.log('INFO', `[Module Dispatcher] Received ${tasks.length} tasks. Creating batches...`);
24
29
 
25
30
  for (let i = 0; i < tasks.length; i += batchSize) {
26
- const batch = tasks.slice(i, i + batchSize);
31
+ const batch = tasks.slice(i, i + batchSize); // e.g., batch is [task1, task2, ... task100]
27
32
 
28
33
  try {
29
- await Promise.all(batch.map(task => topic.publishMessage({ json: task })));
34
+ // --- START MODIFICATION ---
35
+ // Wrap the entire batch of tasks into a single object payload.
36
+ // This is the payload the Task Engine will now receive.
37
+ const messagePayload = { tasks: batch };
38
+
39
+ // Publish the entire batch as a single message
40
+ await topic.publishMessage({ json: messagePayload });
41
+
42
+ // --- END MODIFICATION ---
43
+
30
44
  totalTasksQueued += batch.length;
31
- logger.log('INFO', `[Module Dispatcher] Dispatched batch ${Math.ceil((i + 1) / batchSize)} with ${batch.length} tasks.`);
45
+ logger.log('INFO', `[Module Dispatcher] Dispatched batch ${Math.ceil((i + 1) / batchSize)} with ${batch.length} tasks as a single message.`);
32
46
 
33
47
  if (i + batchSize < tasks.length) {
34
48
  await sleep(batchDelayMs);
@@ -44,4 +58,4 @@ async function dispatchTasksInBatches(tasks, dependencies, config) {
44
58
 
45
59
  module.exports = {
46
60
  dispatchTasksInBatches
47
- };
61
+ };
@@ -2,8 +2,14 @@
2
2
  * @fileoverview Main pipe for the Task Engine.
3
3
  * REFACTORED: This file is now 'handler_creator.js' in name only.
4
4
  * It exports the main 'handleRequest' pipe function.
5
- * OPTIMIZED: Removed 'batchManager.flushBatches()' from 'finally' block
6
- * to enable true asynchronous batching.
5
+ *
6
+ * --- MODIFICATION ---
7
+ * The `handleRequest` function is now designed to receive a *batch*
8
+ * of tasks (e.g., { tasks: [...] }) from the Dispatcher. It loops
9
+ * through all tasks in a single function instance, allowing the
10
+ * FirestoreBatchManager to accumulate state. It then explicitly
11
+ * calls `batchManager.flushBatches()` in the `finally` block
12
+ * to commit all changes.
7
13
  */
8
14
 
9
15
  const { handleDiscover } = require('./helpers/discover_helpers');
@@ -19,7 +25,7 @@ const { handleUpdate } = require('./helpers/update_helpers');
19
25
  * @param {object} dependencies - Contains all clients: db, pubsub, logger, headerManager, proxyManager, batchManager.
20
26
  */
21
27
  async function handleRequest(message, context, config, dependencies) {
22
- // --- OPTIMIZATION: Destructure headerManager here ---
28
+ // --- MODIFICATION: Destructure batchManager and headerManager ---
23
29
  const { logger, batchManager, headerManager } = dependencies;
24
30
 
25
31
  if (!message || !message.data) {
@@ -27,51 +33,73 @@ async function handleRequest(message, context, config, dependencies) {
27
33
  return;
28
34
  }
29
35
 
30
- let task;
36
+ let payload;
31
37
  try {
32
- task = JSON.parse(Buffer.from(message.data, 'base64').toString('utf-8'));
38
+ payload = JSON.parse(Buffer.from(message.data, 'base64').toString('utf-8'));
33
39
  } catch (e) {
34
40
  logger.log('ERROR', '[TaskEngine Module] Failed to parse Pub/Sub message data.', { error: e.message, data: message.data });
35
41
  return;
36
42
  }
37
43
 
38
- const taskId = `${task.type || 'unknown'}-${task.userType || 'unknown'}-${task.userId || task.cids?.[0] || 'batch'}-${Date.now()}`;
39
- logger.log('INFO', `[TaskEngine/${taskId}] Received.`);
44
+ // --- START MODIFICATION: Handle Batch Payload ---
45
+
46
+ // Check if this is a batched task payload
47
+ if (!payload.tasks || !Array.isArray(payload.tasks)) {
48
+ logger.log('ERROR', `[TaskEngine] Received invalid payload. Expected { tasks: [...] }`, { payload });
49
+ return;
50
+ }
51
+
52
+ if (payload.tasks.length === 0) {
53
+ logger.log('WARN', '[TaskEngine] Received message with an empty tasks array.');
54
+ return;
55
+ }
56
+
57
+ const taskId = `batch-${payload.tasks[0]?.type || 'unknown'}-${Date.now()}`;
58
+ logger.log('INFO', `[TaskEngine/${taskId}] Received batch of ${payload.tasks.length} tasks.`);
40
59
 
41
60
  try {
42
- await new Promise(resolve => setTimeout(resolve, Math.random() * 500 + 250));
61
+ // Loop through all tasks in this single function instance
62
+ for (const task of payload.tasks) {
63
+
64
+ // Generate a sub-task ID for logging
65
+ const subTaskId = `${task.type || 'unknown'}-${task.userType || 'unknown'}-${task.userId || task.cids?.[0] || 'sub'}`;
43
66
 
44
- // --- 3. Use the directly required functions ---
45
- // Route to the correct sub-pipe
46
- const handlerFunction = {
47
- discover: handleDiscover,
48
- verify: handleVerify,
49
- update: handleUpdate
50
- }[task.type];
67
+ const handlerFunction = {
68
+ discover: handleDiscover,
69
+ verify: handleVerify,
70
+ update: handleUpdate
71
+ }[task.type];
51
72
 
52
- if (handlerFunction) {
53
- // Pass the dependencies object to the sub-pipe
54
- await handlerFunction(task, taskId, dependencies, config);
55
- logger.log('SUCCESS', `[TaskEngine/${taskId}] Done.`);
56
- } else {
57
- logger.log('ERROR', `[TaskEngine/${taskId}] Unknown task type received: ${task.type}`);
73
+ if (handlerFunction) {
74
+ // We await each one sequentially to manage API load,
75
+ // but they all use the *same* batchManager instance.
76
+ await handlerFunction(task, subTaskId, dependencies, config);
77
+ } else {
78
+ logger.log('ERROR', `[TaskEngine/${taskId}] Unknown task type in batch: ${task.type}`);
79
+ }
58
80
  }
81
+
82
+ logger.log('SUCCESS', `[TaskEngine/${taskId}] Processed ${payload.tasks.length} tasks. Done.`);
83
+
59
84
  } catch (error) {
60
- logger.log('ERROR', `[TaskEngine/${taskId}] Failed.`, { errorMessage: error.message, errorStack: error.stack });
85
+ logger.log('ERROR', `[TaskEngine/${taskId}] Failed during batch processing.`, { errorMessage: error.message, errorStack: error.stack });
61
86
 
62
87
  } finally {
63
88
  try {
64
- // --- OPTIMIZATION START ---
65
- // The FirestoreBatchManager will flush itself on its own timer.
66
- // We no longer call `await batchManager.flushBatches()` here.
67
- // We *only* need to flush the header performance updates at the end of the task.
68
- await headerManager.flushPerformanceUpdates();
69
- logger.log('INFO', `[TaskEngine/${taskId}] Final header performance flush complete.`);
70
- // --- OPTIMIZATION END ---
89
+ // --- MODIFICATION ---
90
+ // This is the most critical change.
91
+ // After the loop (or if an error occurs), explicitly flush
92
+ // all accumulated writes (portfolios, timestamps, etc.)
93
+ // from the batchManager.
94
+ logger.log('INFO', `[TaskEngine/${taskId}] Flushing all accumulated batches...`);
95
+ await batchManager.flushBatches();
96
+ logger.log('INFO', `[TaskEngine/${taskId}] Final batch and header flush complete.`);
97
+ // --- END MODIFICATION ---
71
98
  } catch (flushError) {
72
99
  logger.log('ERROR', `[TaskEngine/${taskId}] Error during final flush attempt.`, { error: flushError.message });
73
100
  }
74
101
  }
102
+ // --- END MODIFICATION ---
75
103
  }
76
104
 
77
105
  module.exports = {
package/index.js CHANGED
@@ -44,7 +44,7 @@ const taskEngine = {
44
44
  handleRequest: require('./functions/task-engine/handler_creator').handleRequest,
45
45
  handleDiscover: require('./functions/task-engine/helpers/discover_helpers').handleDiscover,
46
46
  handleVerify: require('./functions/task-engine/helpers/verify_helpers').handleVerify,
47
- handleUpdate: require('./functions/task-engine/helpers/update_helpers').handleUpdate,pnl
47
+ handleUpdate: require('./functions/task-engine/helpers/update_helpers').handleUpdate,
48
48
  };
49
49
 
50
50
  // --- Pipe 4: Computation System ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.120",
3
+ "version": "1.0.122",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [