Skip to content

Commit c0cd4f5

Browse files
committed
perf: improve science
1 parent 760b346 commit c0cd4f5

File tree

1 file changed

+86
-72
lines changed

1 file changed

+86
-72
lines changed
Lines changed: 86 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,96 @@
11
import { mainLog, mongo, redis } from "../index.js";
2+
import pLimit from "p-limit";
3+
4+
const limit = pLimit(1);
25

36
export default async function () {
4-
const log = mainLog.extend("updateScience"),
5-
key = "pmd-api.scienceUpdates";
6-
7-
log("Updating...");
8-
const scienceUpdates = await redis.hvals(key);
9-
10-
let invalidEntries: string[] = [],
11-
entries: {
12-
identifier: string;
13-
presences: string[];
14-
platform: { os: string; arch: string };
15-
updated: number;
16-
}[] = [];
17-
18-
for (const u of scienceUpdates) {
19-
try {
20-
const e = JSON.parse(u);
21-
22-
entries.push({
23-
identifier: e.identifier,
24-
presences: e.presences,
25-
platform: {
26-
arch: e.platform.arch,
27-
os: e.platform.os
28-
},
29-
updated: Date.now()
30-
});
31-
} catch (e) {
32-
invalidEntries.push(u);
33-
//* Invalid entry
7+
return limit(async () => {
8+
const log = mainLog.extend("updateScience"),
9+
key = "pmd-api.scienceUpdates";
10+
11+
log("Updating...");
12+
const scienceUpdates = await redis.hvals(key);
13+
14+
let invalidEntries = [],
15+
entries = [];
16+
17+
for (const u of scienceUpdates) {
18+
try {
19+
const e = JSON.parse(u);
20+
21+
entries.push({
22+
identifier: e.identifier,
23+
presences: e.presences,
24+
platform: {
25+
arch: e.platform.arch,
26+
os: e.platform.os
27+
},
28+
updated: Date.now()
29+
});
30+
} catch (e) {
31+
invalidEntries.push(u);
32+
}
3433
}
35-
}
36-
37-
if (invalidEntries.length) {
38-
await redis.hdel(key, ...invalidEntries);
39-
log("Deleted %n invalid entries", invalidEntries.length);
40-
}
41-
42-
if (entries.length) {
43-
const res = await mongo
44-
.db("PreMiD")
45-
.collection("science")
46-
.bulkWrite(
47-
entries.map(e => ({
48-
updateOne: {
49-
filter: { identifier: e.identifier },
50-
update: { $set: e },
51-
upsert: true
52-
}
53-
}))
54-
);
55-
56-
await redis.hdel(key, ...entries.map(e => e.identifier));
57-
58-
log(
59-
"Inserted %s entries, Updated %s entries",
60-
res.upsertedCount,
61-
res.modifiedCount
62-
);
63-
} else log("No entries to update");
64-
65-
const delRedis = await redis.hvals("pmd-api.scienceDeletes");
66-
67-
let orMatch: any[] = [
68-
{
69-
updated: { $lt: Date.now() - 31 * 24 * 60 * 60 * 1000 }
34+
35+
if (invalidEntries.length) {
36+
await redis.hdel(key, ...invalidEntries);
37+
log("Deleted %n invalid entries", invalidEntries.length);
7038
}
71-
];
7239

73-
if (delRedis.length) orMatch.push({ identifier: { $in: delRedis } });
40+
if (entries.length) {
41+
const bulkOps = entries.map(e => ({
42+
updateOne: {
43+
filter: { identifier: e.identifier },
44+
update: { $set: e },
45+
upsert: true
46+
}
47+
}));
7448

75-
const delRes = await mongo.db("PreMiD").collection("science").deleteMany({
76-
$or: orMatch
77-
});
49+
// Batch the bulk operations for better performance
50+
const BATCH_SIZE = 1000;
51+
for (let i = 0; i < bulkOps.length; i += BATCH_SIZE) {
52+
const batch = bulkOps.slice(i, i + BATCH_SIZE);
53+
const res = await mongo
54+
.db("PreMiD")
55+
.collection("science")
56+
.bulkWrite(batch);
57+
log(
58+
"Batch %s: Inserted %s entries, Updated %s entries",
59+
Math.floor(i / BATCH_SIZE) + 1,
60+
res.upsertedCount,
61+
res.modifiedCount
62+
);
63+
}
64+
65+
await redis.hdel(key, ...entries.map(e => e.identifier));
66+
} else {
67+
log("No entries to update");
68+
}
7869

79-
if (delRedis.length) await redis.hdel("pmd-api.scienceDeletes", ...delRedis);
70+
const delRedis = await redis.hvals("pmd-api.scienceDeletes");
8071

81-
if (delRes.deletedCount) log("Deleted %s entries", delRes.deletedCount);
72+
let orMatch: any[] = [
73+
{
74+
updated: { $lt: Date.now() - 31 * 24 * 60 * 60 * 1000 }
75+
}
76+
];
77+
78+
if (delRedis.length) {
79+
orMatch.push({ identifier: { $in: delRedis } });
80+
}
81+
82+
const delCollection = mongo.db("PreMiD").collection("science");
83+
84+
const delRes = await delCollection.deleteMany({
85+
$or: orMatch
86+
});
87+
88+
if (delRedis.length) {
89+
await redis.hdel("pmd-api.scienceDeletes", ...delRedis);
90+
}
91+
92+
if (delRes.deletedCount) {
93+
log("Deleted %s entries", delRes.deletedCount);
94+
}
95+
});
8296
}

0 commit comments

Comments
 (0)