Skip to content

Commit 001b9dc

Browse files
committed
refactor: make migrating endpoint asynchronous
1 parent e49ea8f commit 001b9dc

2 files changed

Lines changed: 49 additions & 35 deletions

File tree

src/analytics.ts

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -104,38 +104,50 @@ export async function upsertSystemInfo(
104104
);
105105
}
106106

107-
export async function migrateFromSqlite() {
108-
const rows = await prisma.telemetrySystemInfo.findMany();
109-
if (rows.length === 0) {
110-
return { migrated: 0, message: "No rows to migrate." };
111-
}
112-
113-
let migrated = 0;
114-
for (const row of rows) {
115-
const desktops = JSON.parse(row.desktops) as string[];
116-
const screens = JSON.parse(row.screens);
117-
118-
await upsertSystemInfo({
119-
userId: row.userId,
120-
date: row.date,
121-
desktops,
122-
vicinaeVersion: row.vicinaeVersion,
123-
displayProtocol: row.displayProtocol,
124-
architecture: row.architecture,
125-
operatingSystem: row.operatingSystem,
126-
buildProvenance: row.buildProvenance,
127-
locale: row.locale,
128-
screens,
129-
chassisType: row.chassisType,
130-
kernelVersion: row.kernelVersion,
131-
productId: row.productId,
132-
productVersion: row.productVersion,
133-
qtVersion: row.qtVersion ?? undefined,
134-
});
135-
migrated++;
136-
}
107+
let migrationRunning = false;
108+
109+
export function startMigration() {
110+
if (migrationRunning) return false;
111+
migrationRunning = true;
112+
113+
(async () => {
114+
const rows = await prisma.telemetrySystemInfo.findMany();
115+
console.log(`[migration] starting: ${rows.length} rows`);
116+
if (rows.length === 0) return;
117+
118+
let migrated = 0;
119+
for (const row of rows) {
120+
await upsertSystemInfo({
121+
userId: row.userId,
122+
date: row.date,
123+
desktops: JSON.parse(row.desktops),
124+
vicinaeVersion: row.vicinaeVersion,
125+
displayProtocol: row.displayProtocol,
126+
architecture: row.architecture,
127+
operatingSystem: row.operatingSystem,
128+
buildProvenance: row.buildProvenance,
129+
locale: row.locale,
130+
screens: JSON.parse(row.screens),
131+
chassisType: row.chassisType,
132+
kernelVersion: row.kernelVersion,
133+
productId: row.productId,
134+
productVersion: row.productVersion,
135+
qtVersion: row.qtVersion ?? undefined,
136+
});
137+
138+
migrated++;
139+
if (migrated % 100 === 0) {
140+
console.log(`[migration] ${migrated}/${rows.length}`);
141+
}
142+
}
143+
console.log(`[migration] complete: ${migrated} rows`);
144+
})().catch((err) => {
145+
console.error("[migration] failed:", err);
146+
}).finally(() => {
147+
migrationRunning = false;
148+
});
137149

138-
return { migrated, message: `Migrated ${migrated} rows from SQLite to DuckDB.` };
150+
return true;
139151
}
140152

141153
export async function deleteUserData(userId: string) {

src/routes/v1/admin.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
queryRawRows,
55
queryStats,
66
queryAnalytics,
7-
migrateFromSqlite,
7+
startMigration,
88
VALID_GRANULARITIES,
99
ALLOWED_FILTERS,
1010
type Granularity,
@@ -72,9 +72,11 @@ admin.get("/analytics", async (c) => {
7272
return c.json({ data, filters, granularity, periods });
7373
});
7474

75-
admin.post("/telemetry/migrate", async (c) => {
76-
const result = await migrateFromSqlite();
77-
return c.json(result);
75+
admin.post("/telemetry/migrate", (c) => {
76+
if (!startMigration()) {
77+
return c.json({ error: "Migration already in progress" }, 409);
78+
}
79+
return c.json({ message: "Migration started" }, 202);
7880
});
7981

8082
export default admin;

0 commit comments

Comments
 (0)