bulltrackers-module 1.0.21 → 1.0.22
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.
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Factory function to create the Computation System handler.
|
|
3
|
+
*/
|
|
4
|
+
const { Firestore } = require('@google-cloud/firestore'); // Needed if db is not passed in
|
|
5
|
+
const { logger: defaultLogger } = require("sharedsetup")(__filename); // Use default logger if none provided
|
|
6
|
+
const { runComputationOrchestrator } = require('./helpers/orchestration_helpers');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates the Computation System Cloud Function handler (HTTP triggered).
|
|
10
|
+
* @param {object} config - The Computation System configuration object (can be empty if not needed by the orchestrator directly).
|
|
11
|
+
* @param {object} [dependencies] - Optional dependencies. If not provided, initializes defaults.
|
|
12
|
+
* @param {Firestore} [dependencies.firestore] - Firestore client instance.
|
|
13
|
+
* @param {object} [dependencies.logger] - Logger instance.
|
|
14
|
+
* @returns {Function} The async Cloud Function handler for HTTP requests.
|
|
15
|
+
*/
|
|
16
|
+
function createComputationSystemHandler(config, dependencies = {}) {
|
|
17
|
+
// Initialize clients using provided dependencies or defaults
|
|
18
|
+
const firestore = dependencies.firestore || new Firestore();
|
|
19
|
+
const logger = dependencies.logger || defaultLogger;
|
|
20
|
+
|
|
21
|
+
// Return the actual handler function (Express middleware format)
|
|
22
|
+
return async (req, res) => {
|
|
23
|
+
const functionName = 'ComputationSystem'; // Or derive dynamically if needed
|
|
24
|
+
logger.log('INFO', `[${functionName}] Starting...`);
|
|
25
|
+
try {
|
|
26
|
+
// Delegate the core logic to the orchestration helper
|
|
27
|
+
// Pass the initialized firestore and logger
|
|
28
|
+
const summary = await runComputationOrchestrator(firestore, logger);
|
|
29
|
+
|
|
30
|
+
logger.log('SUCCESS', `[${functionName}] Done.`);
|
|
31
|
+
// Send success response if headers not already sent
|
|
32
|
+
if (!res.headersSent) {
|
|
33
|
+
res.status(200).send({ message: 'Computation complete', summary });
|
|
34
|
+
}
|
|
35
|
+
} catch (error) {
|
|
36
|
+
logger.log('ERROR', `[${functionName}] Failed.`, { errorMessage: error.message, errorStack: error.stack });
|
|
37
|
+
// Send error response if headers not already sent
|
|
38
|
+
if (!res.headersSent) {
|
|
39
|
+
res.status(500).send({ message: 'Computation Error', error: error.message });
|
|
40
|
+
}
|
|
41
|
+
// Optional: Re-throw if you want Cloud Functions/Run to explicitly log the failure higher up
|
|
42
|
+
// throw error;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
module.exports = {
|
|
48
|
+
createComputationSystemHandler,
|
|
49
|
+
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Exports the computation system's main logic.
|
|
2
|
+
* @fileoverview Exports the computation system's main logic and handler creator.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const { runComputationOrchestrator } = require('./helpers/orchestration_helpers.js');
|
|
6
|
+
const { createComputationSystemHandler } = require('./handler_creator.js'); // <-- Import the new factory
|
|
6
7
|
|
|
7
8
|
module.exports = {
|
|
8
9
|
runComputationOrchestrator,
|
|
10
|
+
createComputationSystemHandler, // <-- Export the factory
|
|
9
11
|
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Factory function to create the Task Engine handler.
|
|
3
|
+
*/
|
|
4
|
+
const { Firestore } = require('@google-cloud/firestore'); // Needed if db is not passed in
|
|
5
|
+
const { PubSub } = require('@google-cloud/pubsub'); // Needed if pubsub is not passed in
|
|
6
|
+
const { logger: defaultLogger } = require("sharedsetup")(__filename); // Use default logger if none provided
|
|
7
|
+
const { core } = require('../../'); // Access core utilities like managers
|
|
8
|
+
const TaskEngineHelpers = require('./helpers');
|
|
9
|
+
const TaskEngineUtils = require('./utils');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Creates the Task Engine Cloud Function handler.
|
|
13
|
+
* @param {object} config - The Task Engine configuration object (e.g., cfg.taskEngine).
|
|
14
|
+
* @param {object} [dependencies] - Optional dependencies. If not provided, initializes defaults.
|
|
15
|
+
* @param {Firestore} [dependencies.firestore] - Firestore client instance.
|
|
16
|
+
* @param {PubSub} [dependencies.pubsub] - PubSub client instance.
|
|
17
|
+
* @param {object} [dependencies.logger] - Logger instance.
|
|
18
|
+
* @returns {Function} The async Cloud Function handler for Pub/Sub messages.
|
|
19
|
+
*/
|
|
20
|
+
function createTaskEngineHandler(config, dependencies = {}) {
|
|
21
|
+
// Initialize clients using provided dependencies or defaults
|
|
22
|
+
const firestore = dependencies.firestore || new Firestore();
|
|
23
|
+
const pubsub = dependencies.pubsub || new PubSub();
|
|
24
|
+
const logger = dependencies.logger || defaultLogger; // Use provided or default logger
|
|
25
|
+
|
|
26
|
+
// Initialize managers and batch manager within this scope
|
|
27
|
+
const headerManager = new core.utils.IntelligentHeaderManager(firestore, logger, config);
|
|
28
|
+
const proxyManager = new core.utils.IntelligentProxyManager(firestore, logger, config);
|
|
29
|
+
const batchManager = new TaskEngineUtils.FirestoreBatchManager(firestore, headerManager, config); // Pass headerManager
|
|
30
|
+
|
|
31
|
+
const CLIENTS = {
|
|
32
|
+
pubsub,
|
|
33
|
+
nativeFirestore: firestore, // Pass the initialized Firestore instance
|
|
34
|
+
headerManager,
|
|
35
|
+
proxyManager,
|
|
36
|
+
batchManager
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Return the actual handler function
|
|
40
|
+
return async (message) => {
|
|
41
|
+
// Basic check for message structure (Cloud Functions Pub/Sub trigger)
|
|
42
|
+
if (!message || !message.data) {
|
|
43
|
+
logger.log('ERROR', '[TaskEngine Module] Received invalid message structure.', { message });
|
|
44
|
+
// Acknowledge Pub/Sub by not throwing, but log error
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let task;
|
|
49
|
+
try {
|
|
50
|
+
// Decode the message
|
|
51
|
+
task = JSON.parse(Buffer.from(message.data, 'base64').toString('utf-8'));
|
|
52
|
+
} catch (e) {
|
|
53
|
+
logger.log('ERROR', '[TaskEngine Module] Failed to parse Pub/Sub message data.', { error: e.message, data: message.data });
|
|
54
|
+
// Acknowledge Pub/Sub by not throwing
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Generate a unique ID for logging this specific task execution
|
|
59
|
+
const taskId = `${task.type || 'unknown'}-${task.userType || 'unknown'}-${task.userId || task.cids?.[0] || 'batch'}-${Date.now()}`;
|
|
60
|
+
logger.log('INFO', `[TaskEngine/${taskId}] Received.`);
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
// Optional: Random delay
|
|
64
|
+
await new Promise(resolve => setTimeout(resolve, Math.random() * 500 + 250));
|
|
65
|
+
|
|
66
|
+
// Determine the correct handler function based on task type
|
|
67
|
+
const handlerFunction = {
|
|
68
|
+
discover: TaskEngineHelpers.handleDiscover,
|
|
69
|
+
verify: TaskEngineHelpers.handleVerify,
|
|
70
|
+
update: TaskEngineHelpers.handleUpdate
|
|
71
|
+
}[task.type];
|
|
72
|
+
|
|
73
|
+
// Execute the handler or log an error if the type is unknown
|
|
74
|
+
if (handlerFunction) {
|
|
75
|
+
await handlerFunction(task, taskId, CLIENTS, config); // Pass CLIENTS and config
|
|
76
|
+
logger.log('SUCCESS', `[TaskEngine/${taskId}] Done.`);
|
|
77
|
+
} else {
|
|
78
|
+
logger.log('ERROR', `[TaskEngine/${taskId}] Unknown task type received: ${task.type}`);
|
|
79
|
+
// Acknowledge Pub/Sub by not throwing
|
|
80
|
+
}
|
|
81
|
+
} catch (error) {
|
|
82
|
+
// Log the error but crucially *do not re-throw* if you want Pub/Sub to ack the message
|
|
83
|
+
// Only re-throw if you want Pub/Sub to attempt redelivery based on its settings.
|
|
84
|
+
// Your existing logic logs but then re-throws - decide if that's the desired behavior.
|
|
85
|
+
logger.log('ERROR', `[TaskEngine/${taskId}] Failed.`, { errorMessage: error.message, errorStack: error.stack });
|
|
86
|
+
// throw error; // Optional: Uncomment if you want Pub/Sub to retry
|
|
87
|
+
} finally {
|
|
88
|
+
// Ensure batches are flushed eventually, though the batch manager handles timed flushes.
|
|
89
|
+
// A final flush here might be redundant if the instance stays alive, but could be useful
|
|
90
|
+
// if the instance might terminate immediately after processing.
|
|
91
|
+
try {
|
|
92
|
+
// Consider if flushing on every single message is desired vs relying on timed flush
|
|
93
|
+
// await batchManager.flushBatches();
|
|
94
|
+
} catch (flushError) {
|
|
95
|
+
logger.log('ERROR', `[TaskEngine/${taskId}] Error during final flush attempt.`, { error: flushError.message });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = {
|
|
102
|
+
createTaskEngineHandler,
|
|
103
|
+
};
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
const helpers = require('./helpers');
|
|
6
6
|
const utils = require('./utils');
|
|
7
|
+
const { createTaskEngineHandler } = require('./handler_creator'); // <-- Import the new factory
|
|
7
8
|
|
|
8
9
|
module.exports = {
|
|
9
10
|
helpers,
|
|
10
11
|
utils,
|
|
12
|
+
createTaskEngineHandler, // <-- Export the factory
|
|
11
13
|
};
|