@powersync/service-module-postgres 0.0.0-dev-20241001150444 → 0.0.0-dev-20241002180742
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.
- package/CHANGELOG.md +11 -6
- package/dist/api/PostgresRouteAPIAdapter.js +2 -0
- package/dist/api/PostgresRouteAPIAdapter.js.map +1 -1
- package/dist/auth/SupabaseKeyCollector.js.map +1 -1
- package/dist/module/PostgresModule.js.map +1 -1
- package/dist/replication/ConnectionManagerFactory.js.map +1 -1
- package/dist/replication/PgManager.js.map +1 -1
- package/dist/replication/PgRelation.js.map +1 -1
- package/dist/replication/PostgresErrorRateLimiter.d.ts +0 -1
- package/dist/replication/PostgresErrorRateLimiter.js.map +1 -1
- package/dist/replication/WalStream.d.ts +0 -1
- package/dist/replication/WalStream.js +8 -4
- package/dist/replication/WalStream.js.map +1 -1
- package/dist/replication/WalStreamReplicationJob.js.map +1 -1
- package/dist/replication/WalStreamReplicator.js.map +1 -1
- package/dist/replication/replication-utils.js.map +1 -1
- package/dist/types/types.js.map +1 -1
- package/dist/utils/migration_lib.js.map +1 -1
- package/dist/utils/pgwire_utils.js.map +1 -1
- package/dist/utils/populate_test_data.js +2 -41
- package/dist/utils/populate_test_data.js.map +1 -1
- package/dist/utils/populate_test_data_worker.d.ts +1 -0
- package/dist/utils/populate_test_data_worker.js +46 -0
- package/dist/utils/populate_test_data_worker.js.map +1 -0
- package/package.json +9 -9
- package/src/api/PostgresRouteAPIAdapter.ts +4 -2
- package/src/replication/PgManager.ts +4 -1
- package/src/replication/PgRelation.ts +1 -1
- package/src/replication/WalStream.ts +11 -4
- package/src/utils/populate_test_data.ts +2 -42
- package/src/utils/populate_test_data_worker.ts +50 -0
- package/test/src/wal_stream_utils.ts +4 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/vitest.config.ts +7 -1
|
@@ -196,15 +196,22 @@ export class WalStream {
|
|
|
196
196
|
// We peek a large number of changes here, to make it more likely to pick up replication slot errors.
|
|
197
197
|
// For example, "publication does not exist" only occurs here if the peek actually includes changes related
|
|
198
198
|
// to the slot.
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
199
|
+
logger.info(`Checking ${slotName}`);
|
|
200
|
+
|
|
201
|
+
// The actual results can be quite large, so we don't actually return everything
|
|
202
|
+
// due to memory and processing overhead that would create.
|
|
203
|
+
const cursor = await this.connections.pool.stream({
|
|
204
|
+
statement: `SELECT 1 FROM pg_catalog.pg_logical_slot_peek_binary_changes($1, NULL, 1000, 'proto_version', '1', 'publication_names', $2)`,
|
|
203
205
|
params: [
|
|
204
206
|
{ type: 'varchar', value: slotName },
|
|
205
207
|
{ type: 'varchar', value: PUBLICATION_NAME }
|
|
206
208
|
]
|
|
207
209
|
});
|
|
210
|
+
|
|
211
|
+
for await (let _chunk of cursor) {
|
|
212
|
+
// No-op, just exhaust the cursor
|
|
213
|
+
}
|
|
214
|
+
|
|
208
215
|
// Success
|
|
209
216
|
logger.info(`Slot ${slotName} appears healthy`);
|
|
210
217
|
return { needsInitialSync: false };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads';
|
|
1
|
+
import { Worker } from 'node:worker_threads';
|
|
3
2
|
|
|
4
3
|
import * as pgwire from '@powersync/service-jpgwire';
|
|
5
4
|
|
|
@@ -12,49 +11,10 @@ export interface PopulateDataOptions {
|
|
|
12
11
|
size: number;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
if (isMainThread || parentPort == null) {
|
|
16
|
-
// Not a worker - ignore
|
|
17
|
-
} else {
|
|
18
|
-
try {
|
|
19
|
-
const options = workerData as PopulateDataOptions;
|
|
20
|
-
|
|
21
|
-
const result = await populateDataInner(options);
|
|
22
|
-
parentPort.postMessage(result);
|
|
23
|
-
process.exit(0);
|
|
24
|
-
} catch (e) {
|
|
25
|
-
// This is a bug, not a connection issue
|
|
26
|
-
console.error(e);
|
|
27
|
-
// Only closes the Worker thread
|
|
28
|
-
process.exit(2);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async function populateDataInner(options: PopulateDataOptions) {
|
|
33
|
-
// Dedicated connection so we can release the memory easily
|
|
34
|
-
const initialDb = await pgwire.connectPgWire(options.connection, { type: 'standard' });
|
|
35
|
-
const largeDescription = crypto.randomBytes(options.size / 2).toString('hex');
|
|
36
|
-
let operation_count = 0;
|
|
37
|
-
for (let i = 0; i < options.num_transactions; i++) {
|
|
38
|
-
const prefix = `test${i}K`;
|
|
39
|
-
|
|
40
|
-
await initialDb.query({
|
|
41
|
-
statement: `INSERT INTO test_data(id, description, other) SELECT $1 || i, $2, 'foo' FROM generate_series(1, $3) i`,
|
|
42
|
-
params: [
|
|
43
|
-
{ type: 'varchar', value: prefix },
|
|
44
|
-
{ type: 'varchar', value: largeDescription },
|
|
45
|
-
{ type: 'int4', value: options.per_transaction }
|
|
46
|
-
]
|
|
47
|
-
});
|
|
48
|
-
operation_count += options.per_transaction;
|
|
49
|
-
}
|
|
50
|
-
await initialDb.end();
|
|
51
|
-
return operation_count;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
14
|
export async function populateData(options: PopulateDataOptions) {
|
|
55
15
|
const WORKER_TIMEOUT = 30_000;
|
|
56
16
|
|
|
57
|
-
const worker = new Worker(new URL('./
|
|
17
|
+
const worker = new Worker(new URL('./populate_test_data_worker.js', import.meta.url), {
|
|
58
18
|
workerData: options
|
|
59
19
|
});
|
|
60
20
|
const timeout = setTimeout(() => {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as crypto from 'crypto';
|
|
2
|
+
import { isMainThread, parentPort, workerData } from 'node:worker_threads';
|
|
3
|
+
|
|
4
|
+
import * as pgwire from '@powersync/service-jpgwire';
|
|
5
|
+
import type { PopulateDataOptions } from './populate_test_data.js';
|
|
6
|
+
|
|
7
|
+
// This util is actually for tests only, but we need it compiled to JS for the service to work, so it's placed in the service.
|
|
8
|
+
|
|
9
|
+
if (isMainThread || parentPort == null) {
|
|
10
|
+
// Must not be imported - only expected to run in a worker
|
|
11
|
+
throw new Error('Do not import this file');
|
|
12
|
+
} else {
|
|
13
|
+
try {
|
|
14
|
+
const options = workerData as PopulateDataOptions;
|
|
15
|
+
if (options == null) {
|
|
16
|
+
throw new Error('loaded worker without options');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const result = await populateDataInner(options);
|
|
20
|
+
parentPort.postMessage(result);
|
|
21
|
+
process.exit(0);
|
|
22
|
+
} catch (e) {
|
|
23
|
+
// This is a bug, not a connection issue
|
|
24
|
+
console.error(e);
|
|
25
|
+
// Only closes the Worker thread
|
|
26
|
+
process.exit(2);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function populateDataInner(options: PopulateDataOptions) {
|
|
31
|
+
// Dedicated connection so we can release the memory easily
|
|
32
|
+
const initialDb = await pgwire.connectPgWire(options.connection, { type: 'standard' });
|
|
33
|
+
const largeDescription = crypto.randomBytes(options.size / 2).toString('hex');
|
|
34
|
+
let operation_count = 0;
|
|
35
|
+
for (let i = 0; i < options.num_transactions; i++) {
|
|
36
|
+
const prefix = `test${i}K`;
|
|
37
|
+
|
|
38
|
+
await initialDb.query({
|
|
39
|
+
statement: `INSERT INTO test_data(id, description, other) SELECT $1 || i, $2, 'foo' FROM generate_series(1, $3) i`,
|
|
40
|
+
params: [
|
|
41
|
+
{ type: 'varchar', value: prefix },
|
|
42
|
+
{ type: 'varchar', value: largeDescription },
|
|
43
|
+
{ type: 'int4', value: options.per_transaction }
|
|
44
|
+
]
|
|
45
|
+
});
|
|
46
|
+
operation_count += options.per_transaction;
|
|
47
|
+
}
|
|
48
|
+
await initialDb.end();
|
|
49
|
+
return operation_count;
|
|
50
|
+
}
|
|
@@ -36,7 +36,10 @@ export class WalStreamTestContext {
|
|
|
36
36
|
public storage?: SyncRulesBucketStorage;
|
|
37
37
|
private replicationConnection?: pgwire.PgConnection;
|
|
38
38
|
|
|
39
|
-
constructor(
|
|
39
|
+
constructor(
|
|
40
|
+
public factory: BucketStorageFactory,
|
|
41
|
+
public connectionManager: PgManager
|
|
42
|
+
) {}
|
|
40
43
|
|
|
41
44
|
async dispose() {
|
|
42
45
|
this.abortController.abort();
|