Skip to content

Commit c68675a

Browse files
authored
Merge pull request #493 from powersync-ja/diagnostics-app-optimizations
Diagnostics app optimizations
2 parents ff10d69 + e1c44ad commit c68675a

File tree

4 files changed

+36
-8
lines changed

4 files changed

+36
-8
lines changed

.changeset/calm-pans-worry.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@powersync/diagnostics-app': minor
3+
---
4+
5+
Improve diagnostics app performance for bulk downloads.

tools/diagnostics-app/src/app/views/sync-diagnostics.tsx

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { NavigationPage } from '@/components/navigation/NavigationPage';
2-
import { clearData, db, syncErrorTracker } from '@/library/powersync/ConnectionManager';
2+
import { clearData, db, sync, syncErrorTracker } from '@/library/powersync/ConnectionManager';
33
import {
44
Box,
55
Button,
@@ -46,6 +46,7 @@ SELECT
4646
stats.metadata_size,
4747
IFNULL(stats.row_count, 0) as row_count,
4848
local.download_size,
49+
local.downloaded_operations,
4950
local.total_operations,
5051
local.downloading
5152
FROM local_bucket_data local
@@ -64,6 +65,7 @@ SELECT
6465
0 as metadata_size,
6566
0 as row_count,
6667
local.download_size,
68+
local.downloaded_operations,
6769
local.total_operations,
6870
local.downloading
6971
FROM local_bucket_data local`;
@@ -81,14 +83,23 @@ export default function SyncDiagnosticsPage() {
8183
// Similar to db.currentState.hasSynced, but synchronized to the onChange events
8284
const { synced_at } = await db.get<{ synced_at: string | null }>('SELECT powersync_last_synced_at() as synced_at');
8385
setlastSyncedAt(synced_at ? new Date(synced_at + 'Z') : null);
84-
if (synced_at != null) {
86+
if (synced_at != null && !sync.syncStatus.dataFlowStatus.downloading) {
8587
// These are potentially expensive queries - do not run during initial sync
8688
const bucketRows = await db.getAll(BUCKETS_QUERY);
8789
const tableRows = await db.getAll(TABLES_QUERY);
8890
setBucketRows(bucketRows);
8991
setTableRows(tableRows);
92+
} else if (synced_at != null) {
93+
// Busy downloading, but have already synced once
94+
const bucketRows = await db.getAll(BUCKETS_QUERY_FAST);
95+
setBucketRows(bucketRows);
96+
// Load tables if we haven't yet
97+
if (tableRows == null) {
98+
const tableRows = await db.getAll(TABLES_QUERY);
99+
setTableRows(tableRows);
100+
}
90101
} else {
91-
// Fast query to show progress during initial sync
102+
// Fast query to show progress during initial sync / while downloading bulk data
92103
const bucketRows = await db.getAll(BUCKETS_QUERY_FAST);
93104
setBucketRows(bucketRows);
94105
setTableRows(null);
@@ -127,6 +138,7 @@ export default function SyncDiagnosticsPage() {
127138
{ field: 'name', headerName: 'Name', flex: 2 },
128139
{ field: 'tables', headerName: 'Table(s)', flex: 1, type: 'text' },
129140
{ field: 'row_count', headerName: 'Row Count', flex: 1, type: 'number' },
141+
{ field: 'downloaded_operations', headerName: 'Downloaded Operations', flex: 1, type: 'number' },
130142
{ field: 'total_operations', headerName: 'Total Operations', flex: 1, type: 'number' },
131143
{
132144
field: 'data_size',
@@ -163,6 +175,7 @@ export default function SyncDiagnosticsPage() {
163175
name: r.name,
164176
tables: JSON.parse(r.tables ?? '[]').join(', '),
165177
row_count: r.row_count,
178+
downloaded_operations: r.downloaded_operations,
166179
total_operations: r.total_operations,
167180
data_size: r.data_size,
168181
metadata_size: r.metadata_size,
@@ -174,6 +187,7 @@ export default function SyncDiagnosticsPage() {
174187
const totals = {
175188
buckets: rows.length,
176189
row_count: rows.reduce((total, row) => total + row.row_count, 0),
190+
downloaded_operations: rows.reduce((total, row) => total + row.downloaded_operations, 0),
177191
total_operations: rows.reduce((total, row) => total + row.total_operations, 0),
178192
data_size: rows.reduce((total, row) => total + row.data_size, 0),
179193
metadata_size: rows.reduce((total, row) => total + row.metadata_size, 0),
@@ -208,6 +222,7 @@ export default function SyncDiagnosticsPage() {
208222
Number of buckets
209223
</TableCell>
210224
<TableCell component="th">Total Rows</TableCell>
225+
<TableCell component="th">Downloaded Operations</TableCell>
211226
<TableCell component="th">Total Operations</TableCell>
212227
<TableCell component="th">Total Data Size</TableCell>
213228
<TableCell component="th">Total Metadata Size</TableCell>
@@ -217,6 +232,7 @@ export default function SyncDiagnosticsPage() {
217232
<TableRow sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
218233
<TableCell align="right">{totals.buckets}</TableCell>
219234
<TableCell align="right">{totals.row_count}</TableCell>
235+
<TableCell align="right">{totals.downloaded_operations}</TableCell>
220236
<TableCell align="right">{totals.total_operations}</TableCell>
221237
<TableCell align="right">{formatBytes(totals.data_size)}</TableCell>
222238
<TableCell align="right">{formatBytes(totals.metadata_size)}</TableCell>

tools/diagnostics-app/src/library/powersync/AppSchema.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const local_bucket_data = new Table(
55
total_operations: column.integer,
66
last_op: column.text,
77
download_size: column.integer,
8+
downloaded_operations: column.integer,
89
downloading: column.integer
910
},
1011
{ localOnly: true }

tools/diagnostics-app/src/library/powersync/RecordingStorageAdapter.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,16 @@ export class RecordingStorageAdapter extends SqliteBucketStorage {
2626
await this.rdb.writeTransaction(async (tx) => {
2727
for (const bucket of checkpoint.buckets) {
2828
await tx.execute(
29-
`INSERT OR REPLACE INTO local_bucket_data(id, total_operations, last_op, download_size, downloading)
29+
`INSERT OR REPLACE INTO local_bucket_data(id, total_operations, last_op, download_size, downloading, downloaded_operations)
3030
VALUES (
3131
?,
3232
?,
3333
IFNULL((SELECT last_op FROM local_bucket_data WHERE id = ?), '0'),
3434
IFNULL((SELECT download_size FROM local_bucket_data WHERE id = ?), 0),
35-
IFNULL((SELECT downloading FROM local_bucket_data WHERE id = ?), TRUE)
35+
IFNULL((SELECT downloading FROM local_bucket_data WHERE id = ?), TRUE),
36+
IFNULL((SELECT downloaded_operations FROM local_bucket_data WHERE id = ?), TRUE)
3637
)`,
37-
[bucket.bucket, bucket.count, bucket.bucket, bucket.bucket, bucket.bucket]
38+
[bucket.bucket, bucket.count, bucket.bucket, bucket.bucket, bucket.bucket, bucket.bucket]
3839
);
3940
}
4041
});
@@ -61,8 +62,13 @@ export class RecordingStorageAdapter extends SqliteBucketStorage {
6162
// Record metrics
6263
const size = JSON.stringify(bucket.data).length;
6364
await tx.execute(
64-
'UPDATE local_bucket_data SET download_size = IFNULL(download_size, 0) + ?, last_op = ?, downloading = ? WHERE id = ?',
65-
[size, bucket.next_after, bucket.has_more, bucket.bucket]
65+
`UPDATE local_bucket_data SET
66+
download_size = IFNULL(download_size, 0) + ?,
67+
last_op = ?,
68+
downloading = ?,
69+
downloaded_operations = IFNULL(downloaded_operations, 0) + ?
70+
WHERE id = ?`,
71+
[size, bucket.next_after, bucket.has_more, bucket.data.length, bucket.bucket]
6672
);
6773
}
6874
});

0 commit comments

Comments
 (0)