bulltrackers-module 1.0.57 → 1.0.59
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,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Main pipe: pipe.maintenance.runUserActivitySampler
|
|
3
3
|
* Samples user activity levels based on the Rankings API.
|
|
4
|
+
* REVISED: Removed exclusion list logic for simplification.
|
|
4
5
|
*/
|
|
5
6
|
const { FieldValue } = require('@google-cloud/firestore');
|
|
6
7
|
|
|
@@ -11,12 +12,13 @@ const { FieldValue } = require('@google-cloud/firestore');
|
|
|
11
12
|
* @returns {Promise<object>} Summary of the sampling process.
|
|
12
13
|
*/
|
|
13
14
|
exports.runUserActivitySampler = async (config, dependencies) => {
|
|
15
|
+
// NOTE: firestoreUtils is still in dependencies but getExclusionIds is no longer called from here.
|
|
14
16
|
const { db, logger, headerManager, proxyManager, firestoreUtils } = dependencies;
|
|
15
17
|
const today = new Date().toISOString().slice(0, 10);
|
|
16
|
-
logger.log('INFO', '[UserActivitySampler] Starting user activity sampling...');
|
|
18
|
+
logger.log('INFO', '[UserActivitySampler] Starting user activity sampling (simplified)...');
|
|
17
19
|
|
|
18
|
-
// Validate configuration
|
|
19
|
-
if (!config.rankingsApiUrl || !config.targetPublicUsersPerBlock || !config.apiBatchSize || !config.outputCollectionName || !config.allHighValueBlocks
|
|
20
|
+
// Validate configuration (Removed exclusionConfig validation)
|
|
21
|
+
if (!config.rankingsApiUrl || !config.targetPublicUsersPerBlock || !config.apiBatchSize || !config.outputCollectionName || !config.allHighValueBlocks ) {
|
|
20
22
|
logger.log('ERROR', '[UserActivitySampler] Missing required configuration.');
|
|
21
23
|
throw new Error('Missing required configuration for User Activity Sampler.');
|
|
22
24
|
}
|
|
@@ -24,14 +26,28 @@ exports.runUserActivitySampler = async (config, dependencies) => {
|
|
|
24
26
|
try {
|
|
25
27
|
await firestoreUtils.resetProxyLocks(dependencies, config); // Use shared config for proxy path
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
// --- REMOVED Exclusion ID fetching ---
|
|
30
|
+
// const exclusionIds = await firestoreUtils.getExclusionIds(dependencies, config.exclusionConfig, 'sampler');
|
|
31
|
+
// logger.log('INFO', `[UserActivitySampler] Fetched ${exclusionIds.size} exclusion IDs.`);
|
|
32
|
+
const processedInThisRun = new Set(); // Keep track of IDs processed in this run to avoid duplicates within batches
|
|
29
33
|
|
|
30
34
|
const blockResults = [];
|
|
31
35
|
let totalPublicSampled = 0;
|
|
32
36
|
let totalPrivateEstimate = 0;
|
|
33
37
|
|
|
38
|
+
// Ensure allHighValueBlocks is defined and is an array
|
|
39
|
+
if (!config.allHighValueBlocks || !Array.isArray(config.allHighValueBlocks)) {
|
|
40
|
+
logger.log('ERROR', '[UserActivitySampler] Configuration error: allHighValueBlocks is missing or not an array.');
|
|
41
|
+
throw new Error('Configuration error: allHighValueBlocks must be an array.');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
34
45
|
for (const block of config.allHighValueBlocks) {
|
|
46
|
+
// Ensure block and block.startId exist
|
|
47
|
+
if (!block || typeof block.startId === 'undefined') {
|
|
48
|
+
logger.log('WARN', '[UserActivitySampler] Skipping invalid block configuration:', block);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
35
51
|
const blockId = block.startId;
|
|
36
52
|
logger.log('INFO', `[UserActivitySampler] Processing block ${blockId}...`);
|
|
37
53
|
|
|
@@ -45,13 +61,14 @@ exports.runUserActivitySampler = async (config, dependencies) => {
|
|
|
45
61
|
while (N_public_sampled_block < config.targetPublicUsersPerBlock && attempts < MAX_ATTEMPTS) {
|
|
46
62
|
attempts++;
|
|
47
63
|
const cidsToSample = [];
|
|
48
|
-
// Generate CIDs, ensuring they are not
|
|
64
|
+
// Generate CIDs, ensuring they are not already processed in this run
|
|
49
65
|
while (cidsToSample.length < config.apiBatchSize) {
|
|
50
66
|
const randomId = String(Math.floor(Math.random() * 1000000) + blockId);
|
|
51
|
-
|
|
67
|
+
// --- REMOVED exclusionIds check, added check for processedInThisRun ---
|
|
68
|
+
if (!processedInThisRun.has(randomId)) {
|
|
52
69
|
cidsToSample.push(parseInt(randomId, 10));
|
|
53
|
-
// Add temporarily to
|
|
54
|
-
|
|
70
|
+
// Add temporarily to processed set for this run to avoid duplicates within batches
|
|
71
|
+
processedInThisRun.add(randomId);
|
|
55
72
|
}
|
|
56
73
|
}
|
|
57
74
|
N_sampled_total_block += cidsToSample.length;
|
|
@@ -70,13 +87,11 @@ exports.runUserActivitySampler = async (config, dependencies) => {
|
|
|
70
87
|
|
|
71
88
|
if (!response || typeof response.json !== 'function') {
|
|
72
89
|
logger.log('WARN', `[UserActivitySampler] Invalid response structure from proxy for block ${blockId}, batch attempt ${attempts}. Skipping batch.`);
|
|
73
|
-
// Consider retrying or specific error handling
|
|
74
90
|
continue; // Skip to next attempt
|
|
75
91
|
}
|
|
76
92
|
|
|
77
93
|
|
|
78
94
|
if (!response.ok) {
|
|
79
|
-
// Log API errors but continue sampling other batches/blocks
|
|
80
95
|
const errorText = await response.text();
|
|
81
96
|
logger.log('WARN', `[UserActivitySampler] API error ${response.status} for block ${blockId}, batch attempt ${attempts}. Skipping batch. Error: ${errorText}`);
|
|
82
97
|
wasSuccess = false;
|
|
@@ -102,13 +117,11 @@ exports.runUserActivitySampler = async (config, dependencies) => {
|
|
|
102
117
|
} catch (fetchError) {
|
|
103
118
|
logger.log('ERROR', `[UserActivitySampler] Fetch failed for block ${blockId}, batch attempt ${attempts}. Skipping batch.`, { errorMessage: fetchError.message });
|
|
104
119
|
wasSuccess = false; // Mark as failure for header performance
|
|
105
|
-
// Continue to next attempt
|
|
106
120
|
} finally {
|
|
107
121
|
if (selectedHeader) {
|
|
108
122
|
headerManager.updatePerformance(selectedHeader.id, wasSuccess);
|
|
109
123
|
}
|
|
110
124
|
}
|
|
111
|
-
// Small delay between batches to avoid overwhelming API/proxies
|
|
112
125
|
await new Promise(resolve => setTimeout(resolve, config.delayBetweenBatchesMs || 200));
|
|
113
126
|
|
|
114
127
|
} // End while loop for block sampling
|
|
@@ -125,7 +138,6 @@ exports.runUserActivitySampler = async (config, dependencies) => {
|
|
|
125
138
|
const now = new Date();
|
|
126
139
|
const oneDayAgo = new Date(now.getTime() - (24 * 60 * 60 * 1000));
|
|
127
140
|
const oneWeekAgo = new Date(now.getTime() - (7 * 24 * 60 * 60 * 1000));
|
|
128
|
-
const oneMonthAgo = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000)); // Approx
|
|
129
141
|
const threeMonthsAgo = new Date(now.getTime() - (90 * 24 * 60 * 60 * 1000)); // Approx
|
|
130
142
|
|
|
131
143
|
|
|
@@ -143,7 +155,7 @@ exports.runUserActivitySampler = async (config, dependencies) => {
|
|
|
143
155
|
|
|
144
156
|
if (lastActivityDate >= oneDayAgo) counts.A1++;
|
|
145
157
|
else if (lastActivityDate >= oneWeekAgo) counts.A2++;
|
|
146
|
-
else if (lastActivityDate >= threeMonthsAgo) counts.A3++;
|
|
158
|
+
else if (lastActivityDate >= threeMonthsAgo) counts.A3++;
|
|
147
159
|
else counts.A4++;
|
|
148
160
|
} catch(e) {
|
|
149
161
|
logger.log('WARN', `[UserActivitySampler] Error parsing LastActivity date '${user.LastActivity}' for user ${user.CID}. Counting as A4.`);
|
|
@@ -157,8 +169,7 @@ exports.runUserActivitySampler = async (config, dependencies) => {
|
|
|
157
169
|
fractions[category] = N_public_sampled_block > 0 ? (counts[category] / N_public_sampled_block) : 0;
|
|
158
170
|
}
|
|
159
171
|
|
|
160
|
-
|
|
161
|
-
const N_block = config.knownTotalUsersPerBlock?.[blockId] || 1000000; // Example fallback
|
|
172
|
+
const N_block = 1000000; // Total users assumed per block
|
|
162
173
|
|
|
163
174
|
const estimatedCounts = {};
|
|
164
175
|
for (const category in fractions) {
|
|
@@ -170,7 +181,7 @@ exports.runUserActivitySampler = async (config, dependencies) => {
|
|
|
170
181
|
sampledDate: today,
|
|
171
182
|
f_private: f_private_block,
|
|
172
183
|
publicSampleSize: N_public_sampled_block,
|
|
173
|
-
totalUsersInBlock: N_block,
|
|
184
|
+
totalUsersInBlock: N_block,
|
|
174
185
|
activityCounts_Sample: counts,
|
|
175
186
|
activityFractions_Sample: fractions,
|
|
176
187
|
estimatedCounts_TotalBlock: estimatedCounts,
|
|
@@ -200,8 +211,7 @@ exports.runUserActivitySampler = async (config, dependencies) => {
|
|
|
200
211
|
|
|
201
212
|
} catch (error) {
|
|
202
213
|
logger.log('ERROR', '[UserActivitySampler] Fatal error during sampling process.', { errorMessage: error.message, errorStack: error.stack });
|
|
203
|
-
// Attempt to flush performance even on error
|
|
204
214
|
try { await headerManager.flushPerformanceUpdates(); } catch (e) { /* ignore flush error */ }
|
|
205
|
-
throw error;
|
|
215
|
+
throw error;
|
|
206
216
|
}
|
|
207
217
|
};
|