bulltrackers-module 1.0.16 → 1.0.17
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,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview
|
|
3
|
+
* Core logic for handling invalid speculator CIDs.
|
|
4
|
+
* Finds or creates a Firestore document and adds the CIDs to it.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Handles the logic of storing invalid speculator IDs.
|
|
9
|
+
*
|
|
10
|
+
* @param {object} message The Pub/Sub message.
|
|
11
|
+
* @param {object} firestore An initialized Firestore client.
|
|
12
|
+
* @param {object} FieldValue A reference to Firestore.FieldValue.
|
|
13
|
+
* @param {object} logger A logger instance.
|
|
14
|
+
* @param {object} config The configuration object.
|
|
15
|
+
* @param {string} config.invalidSpeculatorsCollectionName The name of the Firestore collection.
|
|
16
|
+
* @param {number} config.maxInvalidUsersPerDoc The max number of IDs to store per doc.
|
|
17
|
+
*/
|
|
18
|
+
exports.handleInvalidSpeculator = async (message, firestore, FieldValue, logger, config) => {
|
|
19
|
+
try {
|
|
20
|
+
const { invalidCids } = JSON.parse(Buffer.from(message.data, 'base64').toString());
|
|
21
|
+
|
|
22
|
+
if (!invalidCids || invalidCids.length === 0) {
|
|
23
|
+
logger.log('WARN', 'Received message with no invalid CIDs. Nothing to do.');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Use config for collection name and max doc size
|
|
28
|
+
const collectionRef = firestore.collection(config.invalidSpeculatorsCollectionName);
|
|
29
|
+
const maxPerDoc = config.maxInvalidUsersPerDoc;
|
|
30
|
+
|
|
31
|
+
// Fetch a pool of documents and pick one randomly
|
|
32
|
+
const querySnapshot = await collectionRef
|
|
33
|
+
.where('userCount', '<', maxPerDoc)
|
|
34
|
+
.limit(10) // Fetch up to 10 potential documents
|
|
35
|
+
.get();
|
|
36
|
+
|
|
37
|
+
let targetDocRef;
|
|
38
|
+
|
|
39
|
+
if (!querySnapshot.empty) {
|
|
40
|
+
// Randomly select one of the available documents to reduce contention
|
|
41
|
+
const randomIndex = Math.floor(Math.random() * querySnapshot.docs.length);
|
|
42
|
+
targetDocRef = querySnapshot.docs[randomIndex].ref;
|
|
43
|
+
} else {
|
|
44
|
+
// If no documents have space, create a new one
|
|
45
|
+
targetDocRef = collectionRef.doc();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Atomic update using a transaction
|
|
49
|
+
await firestore.runTransaction(async (transaction) => {
|
|
50
|
+
const doc = await transaction.get(targetDocRef);
|
|
51
|
+
|
|
52
|
+
const updates = {};
|
|
53
|
+
let newUsersCount = 0;
|
|
54
|
+
|
|
55
|
+
if (!doc.exists) {
|
|
56
|
+
// If it's a new document, initialize the user count
|
|
57
|
+
updates.userCount = 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const cid of invalidCids) {
|
|
61
|
+
const fieldPath = `users.${cid}`;
|
|
62
|
+
// Check if the user ID already exists to avoid recounting
|
|
63
|
+
if (!doc.exists || !doc.data().users || !doc.data().users[cid]) {
|
|
64
|
+
updates[fieldPath] = true;
|
|
65
|
+
newUsersCount++;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (newUsersCount > 0) {
|
|
70
|
+
updates.userCount = FieldValue.increment(newUsersCount);
|
|
71
|
+
transaction.set(targetDocRef, updates, { merge: true });
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
logger.log('SUCCESS', `Successfully stored ${invalidCids.length} invalid speculator IDs in document ${targetDocRef.id}.`);
|
|
76
|
+
|
|
77
|
+
} catch (error) {
|
|
78
|
+
logger.log('ERROR', 'FATAL Error in Invalid Speculator Handler', {
|
|
79
|
+
errorMessage: error.message,
|
|
80
|
+
errorStack: error.stack
|
|
81
|
+
});
|
|
82
|
+
// Re-throw the error to ensure Pub/Sub retries the message
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
};
|
package/index.js
CHANGED
|
@@ -10,6 +10,7 @@ const TaskEngine = require('./functions/task-engine');
|
|
|
10
10
|
const ComputationSystem = require('./functions/computation-system');
|
|
11
11
|
const GenericAPI = require('./functions/generic-api'); // <-- ADD THIS
|
|
12
12
|
const Dispatcher = require('./functions/dispatcher'); // <-- ADD THIS
|
|
13
|
+
const InvalidSpeculatorHandler = require('./functions/invalid-speculator-handler'); // <-- ADD THIS
|
|
13
14
|
|
|
14
15
|
module.exports = {
|
|
15
16
|
core,
|
|
@@ -17,5 +18,6 @@ module.exports = {
|
|
|
17
18
|
TaskEngine,
|
|
18
19
|
ComputationSystem,
|
|
19
20
|
GenericAPI, // <-- AND ADD THIS
|
|
20
|
-
Dispatcher, // <-- AND ADD
|
|
21
|
+
Dispatcher, // <-- AND ADD THIS
|
|
22
|
+
InvalidSpeculatorHandler, // <-- AND ADD THIS
|
|
21
23
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bulltrackers-module",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.17",
|
|
4
4
|
"description": "Helper Functions for Bulltrackers.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"functions/core/",
|
|
11
11
|
"functions/computation-system/",
|
|
12
12
|
"functions/generic-api/",
|
|
13
|
-
"functions/dispatcher/"
|
|
13
|
+
"functions/dispatcher/",
|
|
14
|
+
"functions/invalid-speculator-handler/"
|
|
14
15
|
],
|
|
15
16
|
"scripts": {
|
|
16
17
|
"test": "echo \"Error: no test specified\" && exit 1"
|