@powersync/service-core 0.0.0-dev-20240709124106 → 0.0.0-dev-20240718134716
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 +34 -2
- package/dist/metrics/Metrics.d.ts +3 -4
- package/dist/metrics/Metrics.js +0 -51
- package/dist/metrics/Metrics.js.map +1 -1
- package/dist/replication/WalStream.js +8 -6
- package/dist/replication/WalStream.js.map +1 -1
- package/dist/routes/endpoints/socket-route.js +13 -4
- package/dist/routes/endpoints/socket-route.js.map +1 -1
- package/dist/routes/endpoints/sync-stream.js +14 -5
- package/dist/routes/endpoints/sync-stream.js.map +1 -1
- package/dist/routes/route-register.js +1 -0
- package/dist/routes/route-register.js.map +1 -1
- package/dist/sync/RequestTracker.d.ts +9 -0
- package/dist/sync/RequestTracker.js +20 -0
- package/dist/sync/RequestTracker.js.map +1 -0
- package/dist/sync/sync.d.ts +2 -0
- package/dist/sync/sync.js +31 -11
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/util.d.ts +2 -1
- package/dist/sync/util.js +2 -3
- package/dist/sync/util.js.map +1 -1
- package/dist/util/config/collectors/config-collector.d.ts +0 -12
- package/dist/util/config/collectors/config-collector.js +0 -43
- package/dist/util/config/collectors/config-collector.js.map +1 -1
- package/dist/util/config/compound-config-collector.d.ts +29 -3
- package/dist/util/config/compound-config-collector.js +69 -22
- package/dist/util/config/compound-config-collector.js.map +1 -1
- package/package.json +6 -8
- package/src/metrics/Metrics.ts +2 -67
- package/src/replication/WalStream.ts +10 -6
- package/src/routes/endpoints/socket-route.ts +14 -4
- package/src/routes/endpoints/sync-stream.ts +15 -5
- package/src/routes/route-register.ts +1 -0
- package/src/sync/RequestTracker.ts +21 -0
- package/src/sync/sync.ts +41 -11
- package/src/sync/util.ts +6 -3
- package/src/util/config/collectors/config-collector.ts +0 -48
- package/src/util/config/compound-config-collector.ts +87 -23
- package/test/src/sync.test.ts +8 -0
- package/test/src/util.ts +12 -6
- package/test/src/wal_stream.test.ts +16 -21
- package/tsconfig.tsbuildinfo +1 -1
package/dist/sync/sync.js
CHANGED
|
@@ -3,7 +3,6 @@ import { Semaphore } from 'async-mutex';
|
|
|
3
3
|
import { AbortError } from 'ix/aborterror.js';
|
|
4
4
|
import * as util from '../util/util-index.js';
|
|
5
5
|
import { logger } from '@powersync/lib-services-framework';
|
|
6
|
-
import { Metrics } from '../metrics/Metrics.js';
|
|
7
6
|
import { mergeAsyncIterables } from './merge.js';
|
|
8
7
|
import { tokenStream } from './util.js';
|
|
9
8
|
/**
|
|
@@ -12,7 +11,7 @@ import { tokenStream } from './util.js';
|
|
|
12
11
|
const MAX_ACTIVE_CONNECTIONS = 10;
|
|
13
12
|
const syncSemaphore = new Semaphore(MAX_ACTIVE_CONNECTIONS);
|
|
14
13
|
export async function* streamResponse(options) {
|
|
15
|
-
const { storage, params, syncParams, token, tokenStreamOptions, signal } = options;
|
|
14
|
+
const { storage, params, syncParams, token, tokenStreamOptions, tracker, signal } = options;
|
|
16
15
|
// We also need to be able to abort, so we create our own controller.
|
|
17
16
|
const controller = new AbortController();
|
|
18
17
|
if (signal) {
|
|
@@ -24,7 +23,7 @@ export async function* streamResponse(options) {
|
|
|
24
23
|
}
|
|
25
24
|
}
|
|
26
25
|
const ki = tokenStream(token, controller.signal, tokenStreamOptions);
|
|
27
|
-
const stream = streamResponseInner(storage, params, syncParams, controller.signal);
|
|
26
|
+
const stream = streamResponseInner(storage, params, syncParams, tracker, controller.signal);
|
|
28
27
|
// Merge the two streams, and abort as soon as one of the streams end.
|
|
29
28
|
const merged = mergeAsyncIterables([stream, ki], controller.signal);
|
|
30
29
|
try {
|
|
@@ -44,7 +43,7 @@ export async function* streamResponse(options) {
|
|
|
44
43
|
controller.abort();
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
|
-
async function* streamResponseInner(storage, params, syncParams, signal) {
|
|
46
|
+
async function* streamResponseInner(storage, params, syncParams, tracker, signal) {
|
|
48
47
|
// Bucket state of bucket id -> op_id.
|
|
49
48
|
// This starts with the state from the client. May contain buckets that the user do not have access to (anymore).
|
|
50
49
|
let dataBuckets = new Map();
|
|
@@ -73,6 +72,11 @@ async function* streamResponseInner(storage, params, syncParams, signal) {
|
|
|
73
72
|
parameters: syncParams
|
|
74
73
|
});
|
|
75
74
|
if (allBuckets.length > 1000) {
|
|
75
|
+
logger.error(`Too many buckets`, {
|
|
76
|
+
checkpoint,
|
|
77
|
+
user_id: syncParams.user_id,
|
|
78
|
+
buckets: allBuckets.length
|
|
79
|
+
});
|
|
76
80
|
// TODO: Limit number of buckets even before we get to this point
|
|
77
81
|
throw new Error(`Too many buckets: ${allBuckets.length}`);
|
|
78
82
|
}
|
|
@@ -94,11 +98,18 @@ async function* streamResponseInner(storage, params, syncParams, signal) {
|
|
|
94
98
|
continue;
|
|
95
99
|
}
|
|
96
100
|
bucketsToFetch = diff.updatedBuckets.map((c) => c.bucket);
|
|
97
|
-
let message = `Updated checkpoint: ${checkpoint} |
|
|
101
|
+
let message = `Updated checkpoint: ${checkpoint} | `;
|
|
102
|
+
message += `write: ${writeCheckpoint} | `;
|
|
98
103
|
message += `buckets: ${allBuckets.length} | `;
|
|
99
104
|
message += `updated: ${limitedBuckets(diff.updatedBuckets, 20)} | `;
|
|
100
|
-
message += `removed: ${limitedBuckets(diff.removedBuckets, 20)}
|
|
101
|
-
logger.info(message
|
|
105
|
+
message += `removed: ${limitedBuckets(diff.removedBuckets, 20)}`;
|
|
106
|
+
logger.info(message, {
|
|
107
|
+
checkpoint,
|
|
108
|
+
user_id: syncParams.user_id,
|
|
109
|
+
buckets: allBuckets.length,
|
|
110
|
+
updated: diff.updatedBuckets.length,
|
|
111
|
+
removed: diff.removedBuckets.length
|
|
112
|
+
});
|
|
102
113
|
const checksum_line = {
|
|
103
114
|
checkpoint_diff: {
|
|
104
115
|
last_op_id: checkpoint,
|
|
@@ -112,7 +123,7 @@ async function* streamResponseInner(storage, params, syncParams, signal) {
|
|
|
112
123
|
else {
|
|
113
124
|
let message = `New checkpoint: ${checkpoint} | write: ${writeCheckpoint} | `;
|
|
114
125
|
message += `buckets: ${allBuckets.length} ${limitedBuckets(allBuckets, 20)}`;
|
|
115
|
-
logger.info(message);
|
|
126
|
+
logger.info(message, { checkpoint, user_id: syncParams.user_id, buckets: allBuckets.length });
|
|
116
127
|
bucketsToFetch = allBuckets;
|
|
117
128
|
const checksum_line = {
|
|
118
129
|
checkpoint: {
|
|
@@ -127,7 +138,16 @@ async function* streamResponseInner(storage, params, syncParams, signal) {
|
|
|
127
138
|
lastWriteCheckpoint = writeCheckpoint;
|
|
128
139
|
// This incrementally updates dataBuckets with each individual bucket position.
|
|
129
140
|
// At the end of this, we can be sure that all buckets have data up to the checkpoint.
|
|
130
|
-
yield* bucketDataInBatches({
|
|
141
|
+
yield* bucketDataInBatches({
|
|
142
|
+
storage,
|
|
143
|
+
checkpoint,
|
|
144
|
+
bucketsToFetch,
|
|
145
|
+
dataBuckets,
|
|
146
|
+
raw_data,
|
|
147
|
+
binary_data,
|
|
148
|
+
signal,
|
|
149
|
+
tracker
|
|
150
|
+
});
|
|
131
151
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
132
152
|
}
|
|
133
153
|
}
|
|
@@ -168,7 +188,7 @@ async function* bucketDataInBatches(request) {
|
|
|
168
188
|
* Extracted as a separate internal function just to avoid memory leaks.
|
|
169
189
|
*/
|
|
170
190
|
async function* bucketDataBatch(request) {
|
|
171
|
-
const { storage, checkpoint, bucketsToFetch, dataBuckets, raw_data, binary_data, signal } = request;
|
|
191
|
+
const { storage, checkpoint, bucketsToFetch, dataBuckets, raw_data, binary_data, tracker, signal } = request;
|
|
172
192
|
const [_, release] = await syncSemaphore.acquire();
|
|
173
193
|
try {
|
|
174
194
|
// Optimization: Only fetch buckets for which the checksums have changed since the last checkpoint
|
|
@@ -213,7 +233,7 @@ async function* bucketDataBatch(request) {
|
|
|
213
233
|
// iterator memory in case if large data sent.
|
|
214
234
|
yield { data: null, done: false };
|
|
215
235
|
}
|
|
216
|
-
|
|
236
|
+
tracker.addOperationsSynced(r.data.length);
|
|
217
237
|
dataBuckets.set(r.bucket, r.next_after);
|
|
218
238
|
}
|
|
219
239
|
if (!has_more) {
|
package/dist/sync/sync.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/sync/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAI9C,OAAO,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAC3D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/sync/sync.ts"],"names":[],"mappings":"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"}
|
package/dist/sync/util.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
/// <reference types="node" resolution-mode="require"/>
|
|
3
3
|
import * as util from '../util/util-index.js';
|
|
4
|
+
import { RequestTracker } from './RequestTracker.js';
|
|
4
5
|
export type TokenStreamOptions = {
|
|
5
6
|
/**
|
|
6
7
|
* Adds periodic keepalive events
|
|
@@ -23,4 +24,4 @@ export declare function tokenStream(token: {
|
|
|
23
24
|
exp: number;
|
|
24
25
|
}, signal: AbortSignal, options?: Partial<TokenStreamOptions>): AsyncGenerator<util.StreamingSyncKeepalive>;
|
|
25
26
|
export declare function ndjson(iterator: AsyncIterable<string | null | Record<string, any>>): AsyncGenerator<string>;
|
|
26
|
-
export declare function transformToBytesTracked(iterator: AsyncIterable<string
|
|
27
|
+
export declare function transformToBytesTracked(iterator: AsyncIterable<string>, tracker: RequestTracker): AsyncGenerator<Buffer>;
|
package/dist/sync/util.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as timers from 'timers/promises';
|
|
2
|
-
import { Metrics } from '../metrics/Metrics.js';
|
|
3
2
|
const KEEPALIVE_INTERVAL = 20000;
|
|
4
3
|
const DEFAULT_TOKEN_STREAM_OPTIONS = {
|
|
5
4
|
keep_alive: true,
|
|
@@ -63,10 +62,10 @@ export async function* ndjson(iterator) {
|
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
|
-
export async function* transformToBytesTracked(iterator) {
|
|
65
|
+
export async function* transformToBytesTracked(iterator, tracker) {
|
|
67
66
|
for await (let data of iterator) {
|
|
68
67
|
const encoded = Buffer.from(data, 'utf8');
|
|
69
|
-
|
|
68
|
+
tracker.addDataSynced(encoded.length);
|
|
70
69
|
yield encoded;
|
|
71
70
|
}
|
|
72
71
|
}
|
package/dist/sync/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/sync/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/sync/util.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,18 +11,6 @@ export declare abstract class ConfigCollector {
|
|
|
11
11
|
* @returns null if this collector cannot provide a config
|
|
12
12
|
*/
|
|
13
13
|
abstract collectSerialized(runnerConfig: RunnerConfig): Promise<configFile.SerializedPowerSyncConfig | null>;
|
|
14
|
-
/**
|
|
15
|
-
* Collects the PowerSyncConfig settings.
|
|
16
|
-
* Validates and decodes the config.
|
|
17
|
-
* @returns null if this collector cannot provide a config
|
|
18
|
-
*/
|
|
19
|
-
collect(runner_config: RunnerConfig): Promise<configFile.PowerSyncConfig | null>;
|
|
20
|
-
/**
|
|
21
|
-
* Validates input config
|
|
22
|
-
* ts-codec itself doesn't give great validation errors, so we use json schema for that
|
|
23
|
-
*/
|
|
24
|
-
validate(config: configFile.PowerSyncConfig): void;
|
|
25
|
-
decode(encoded: configFile.SerializedPowerSyncConfig): configFile.PowerSyncConfig;
|
|
26
14
|
protected parseContent(content: string, contentType?: ConfigFileFormat): any;
|
|
27
15
|
protected parseYaml(content: string): any;
|
|
28
16
|
protected parseJSON(content: string): any;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import * as t from 'ts-codec';
|
|
2
1
|
import * as yaml from 'yaml';
|
|
3
|
-
import { configFile } from '@powersync/service-types';
|
|
4
|
-
import { schema } from '@powersync/lib-services-framework';
|
|
5
2
|
export var ConfigFileFormat;
|
|
6
3
|
(function (ConfigFileFormat) {
|
|
7
4
|
ConfigFileFormat["YAML"] = "yaml";
|
|
@@ -18,47 +15,7 @@ export var ConfigFileFormat;
|
|
|
18
15
|
* uri: !env PS_MONGO_URI
|
|
19
16
|
*/
|
|
20
17
|
const YAML_ENV_PREFIX = 'PS_';
|
|
21
|
-
// ts-codec itself doesn't give great validation errors, so we use json schema for that
|
|
22
|
-
const configSchemaValidator = schema
|
|
23
|
-
.parseJSONSchema(t.generateJSONSchema(configFile.powerSyncConfig, { allowAdditional: true, parsers: [configFile.portParser] }))
|
|
24
|
-
.validator();
|
|
25
18
|
export class ConfigCollector {
|
|
26
|
-
/**
|
|
27
|
-
* Collects the PowerSyncConfig settings.
|
|
28
|
-
* Validates and decodes the config.
|
|
29
|
-
* @returns null if this collector cannot provide a config
|
|
30
|
-
*/
|
|
31
|
-
async collect(runner_config) {
|
|
32
|
-
const serialized = await this.collectSerialized(runner_config);
|
|
33
|
-
if (!serialized) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* After this point a serialized config has been found. Any failures to decode or validate
|
|
38
|
-
* will result in a hard stop.
|
|
39
|
-
*/
|
|
40
|
-
const decoded = this.decode(serialized);
|
|
41
|
-
this.validate(decoded);
|
|
42
|
-
return decoded;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Validates input config
|
|
46
|
-
* ts-codec itself doesn't give great validation errors, so we use json schema for that
|
|
47
|
-
*/
|
|
48
|
-
validate(config) {
|
|
49
|
-
const valid = configSchemaValidator.validate(config);
|
|
50
|
-
if (!valid.valid) {
|
|
51
|
-
throw new Error(`Failed to validate PowerSync config: ${valid.errors.join(', ')}`);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
decode(encoded) {
|
|
55
|
-
try {
|
|
56
|
-
return configFile.powerSyncConfig.decode(encoded);
|
|
57
|
-
}
|
|
58
|
-
catch (ex) {
|
|
59
|
-
throw new Error(`Failed to decode PowerSync config: ${ex}`);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
19
|
parseContent(content, contentType) {
|
|
63
20
|
switch (contentType) {
|
|
64
21
|
case ConfigFileFormat.YAML:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-collector.js","sourceRoot":"","sources":["../../../../src/util/config/collectors/config-collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"config-collector.js","sourceRoot":"","sources":["../../../../src/util/config/collectors/config-collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAM7B,MAAM,CAAN,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,iCAAa,CAAA;IACb,iCAAa,CAAA;AACf,CAAC,EAHW,gBAAgB,KAAhB,gBAAgB,QAG3B;AAED;;;;;;;;;GASG;AACH,MAAM,eAAe,GAAG,KAAK,CAAC;AAE9B,MAAM,OAAgB,eAAe;IASzB,YAAY,CAAC,OAAe,EAAE,WAA8B;QACpE,QAAQ,WAAW,EAAE;YACnB,KAAK,gBAAgB,CAAC,IAAI;gBACxB,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACjC,KAAK,gBAAgB,CAAC,IAAI;gBACxB,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACjC,OAAO,CAAC,CAAC;gBACP,6CAA6C;gBAC7C,IAAI;oBACF,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;iBAChC;gBAAC,OAAO,EAAE,EAAE,GAAE;gBACf,IAAI;oBACF,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;iBAChC;gBAAC,OAAO,EAAE,EAAE;oBACX,MAAM,IAAI,KAAK,CAAC,kEAAkE,EAAE,EAAE,CAAC,CAAC;iBACzF;aACF;SACF;IACH,CAAC;IAES,SAAS,CAAC,OAAe;QACjC,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QAE3C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,gBAAgB,EAAE,IAAI;YACtB,WAAW;YACX,UAAU,EAAE;gBACV;oBACE,GAAG,EAAE,MAAM;oBACX,OAAO,CAAC,OAAe,EAAE,OAAgC;wBACvD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE;4BACxC,OAAO,CACL,iDAAiD,OAAO,+CAA+C,eAAe,GAAG,CAC1H,CAAC;4BACF,OAAO,OAAO,CAAC;yBAChB;wBACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBACnC,IAAI,OAAO,KAAK,IAAI,WAAW,EAAE;4BAC/B,OAAO,CACL,iDAAiD,OAAO,6DAA6D,CACtH,CAAC;4BACF,OAAO,OAAO,CAAC;yBAChB;wBACD,OAAO,KAAK,CAAC;oBACf,CAAC;iBACF;aACF;SACF,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE;YACxB,MAAM,IAAI,KAAK,CACb,gEAAgE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACjH,CAAC;SACH;QAED,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAES,SAAS,CAAC,OAAe;QACjC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as t from 'ts-codec';
|
|
1
2
|
import { configFile } from '@powersync/service-types';
|
|
2
3
|
import { ConfigCollector } from './collectors/config-collector.js';
|
|
3
4
|
import { ResolvedPowerSyncConfig, RunnerConfig, SyncRulesConfig } from './types.js';
|
|
@@ -16,17 +17,42 @@ export type CompoundConfigCollectorOptions = {
|
|
|
16
17
|
*/
|
|
17
18
|
syncRulesCollectors: SyncRulesCollector[];
|
|
18
19
|
};
|
|
19
|
-
export
|
|
20
|
+
export type ConfigCollectorGenerics = {
|
|
21
|
+
SERIALIZED: configFile.SerializedPowerSyncConfig;
|
|
22
|
+
DESERIALIZED: configFile.PowerSyncConfig;
|
|
23
|
+
RESOLVED: ResolvedPowerSyncConfig;
|
|
24
|
+
};
|
|
25
|
+
export declare class CompoundConfigCollector<Generics extends ConfigCollectorGenerics = ConfigCollectorGenerics> {
|
|
20
26
|
protected options: CompoundConfigCollectorOptions;
|
|
21
27
|
constructor(options?: CompoundConfigCollectorOptions);
|
|
28
|
+
/**
|
|
29
|
+
* The default ts-codec for validations and decoding
|
|
30
|
+
*/
|
|
31
|
+
get codec(): t.AnyCodec;
|
|
22
32
|
/**
|
|
23
33
|
* Collects and resolves base config
|
|
24
34
|
*/
|
|
25
|
-
collectConfig(
|
|
35
|
+
collectConfig(runnerConfig?: RunnerConfig): Promise<Generics['RESOLVED']>;
|
|
26
36
|
/**
|
|
27
37
|
* Collects the base PowerSyncConfig from various registered collectors.
|
|
28
38
|
* @throws if no collector could return a configuration.
|
|
29
39
|
*/
|
|
30
|
-
protected collectBaseConfig(runner_config: RunnerConfig): Promise<
|
|
40
|
+
protected collectBaseConfig(runner_config: RunnerConfig): Promise<Generics['DESERIALIZED']>;
|
|
41
|
+
/**
|
|
42
|
+
* Performs the resolving of the common (shared) base configuration
|
|
43
|
+
*/
|
|
44
|
+
protected resolveBaseConfig(baseConfig: Generics['DESERIALIZED'], runnerConfig?: RunnerConfig): Promise<ResolvedPowerSyncConfig>;
|
|
45
|
+
/**
|
|
46
|
+
* Perform any additional resolving from {@link ResolvedPowerSyncConfig}
|
|
47
|
+
* to the extended {@link Generics['RESOLVED']}
|
|
48
|
+
*
|
|
49
|
+
*/
|
|
50
|
+
protected resolveConfig(baseConfig: Generics['DESERIALIZED'], resolvedBaseConfig: ResolvedPowerSyncConfig, runnerConfig?: RunnerConfig): Promise<Generics['RESOLVED']>;
|
|
31
51
|
protected collectSyncRules(baseConfig: configFile.PowerSyncConfig, runnerConfig: RunnerConfig): Promise<SyncRulesConfig>;
|
|
52
|
+
/**
|
|
53
|
+
* Validates input config
|
|
54
|
+
* ts-codec itself doesn't give great validation errors, so we use json schema for that
|
|
55
|
+
*/
|
|
56
|
+
protected validate(config: Generics['DESERIALIZED']): void;
|
|
57
|
+
protected decode(encoded: Generics['SERIALIZED']): Generics['DESERIALIZED'];
|
|
32
58
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as t from 'ts-codec';
|
|
2
|
+
import { configFile, normalizeConnection } from '@powersync/service-types';
|
|
2
3
|
import * as auth from '../../auth/auth-index.js';
|
|
3
4
|
import { Base64ConfigCollector } from './collectors/impl/base64-config-collector.js';
|
|
4
5
|
import { FileSystemConfigCollector } from './collectors/impl/filesystem-config-collector.js';
|
|
@@ -6,7 +7,7 @@ import { Base64SyncRulesCollector } from './sync-rules/impl/base64-sync-rules-co
|
|
|
6
7
|
import { InlineSyncRulesCollector } from './sync-rules/impl/inline-sync-rules-collector.js';
|
|
7
8
|
import { FileSystemSyncRulesCollector } from './sync-rules/impl/filesystem-sync-rules-collector.js';
|
|
8
9
|
import { FallbackConfigCollector } from './collectors/impl/fallback-config-collector.js';
|
|
9
|
-
import { logger } from '@powersync/lib-services-framework';
|
|
10
|
+
import { logger, schema } from '@powersync/lib-services-framework';
|
|
10
11
|
const POWERSYNC_DEV_KID = 'powersync-dev';
|
|
11
12
|
const DEFAULT_COLLECTOR_OPTIONS = {
|
|
12
13
|
configCollectors: [new Base64ConfigCollector(), new FileSystemConfigCollector(), new FallbackConfigCollector()],
|
|
@@ -20,11 +21,46 @@ export class CompoundConfigCollector {
|
|
|
20
21
|
constructor(options = DEFAULT_COLLECTOR_OPTIONS) {
|
|
21
22
|
this.options = options;
|
|
22
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* The default ts-codec for validations and decoding
|
|
26
|
+
*/
|
|
27
|
+
get codec() {
|
|
28
|
+
return configFile.powerSyncConfig;
|
|
29
|
+
}
|
|
23
30
|
/**
|
|
24
31
|
* Collects and resolves base config
|
|
25
32
|
*/
|
|
26
|
-
async collectConfig(
|
|
27
|
-
const baseConfig = await this.collectBaseConfig(
|
|
33
|
+
async collectConfig(runnerConfig = {}) {
|
|
34
|
+
const baseConfig = await this.collectBaseConfig(runnerConfig);
|
|
35
|
+
const baseResolvedConfig = await this.resolveBaseConfig(baseConfig, runnerConfig);
|
|
36
|
+
return this.resolveConfig(baseConfig, baseResolvedConfig, runnerConfig);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Collects the base PowerSyncConfig from various registered collectors.
|
|
40
|
+
* @throws if no collector could return a configuration.
|
|
41
|
+
*/
|
|
42
|
+
async collectBaseConfig(runner_config) {
|
|
43
|
+
for (const collector of this.options.configCollectors) {
|
|
44
|
+
try {
|
|
45
|
+
const baseConfig = await collector.collectSerialized(runner_config);
|
|
46
|
+
if (baseConfig) {
|
|
47
|
+
const decoded = this.decode(baseConfig);
|
|
48
|
+
this.validate(decoded);
|
|
49
|
+
return decoded;
|
|
50
|
+
}
|
|
51
|
+
logger.debug(`Could not collect PowerSync config with ${collector.name} method. Moving on to next method if available.`);
|
|
52
|
+
}
|
|
53
|
+
catch (ex) {
|
|
54
|
+
// An error in a collector is a hard stop
|
|
55
|
+
throw new Error(`Could not collect config using ${collector.name} method. Caught exception: ${ex}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
throw new Error('PowerSyncConfig could not be collected using any of the registered config collectors.');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Performs the resolving of the common (shared) base configuration
|
|
62
|
+
*/
|
|
63
|
+
async resolveBaseConfig(baseConfig, runnerConfig = {}) {
|
|
28
64
|
const connections = baseConfig.replication?.connections ?? [];
|
|
29
65
|
if (connections.length > 1) {
|
|
30
66
|
throw new Error('Only a single replication connection is supported currently');
|
|
@@ -57,7 +93,7 @@ export class CompoundConfigCollector {
|
|
|
57
93
|
if (baseConfig.dev?.demo_auth && baseDevKey != null && baseDevKey.kty == 'oct') {
|
|
58
94
|
devKey = await auth.KeySpec.importKey(baseDevKey);
|
|
59
95
|
}
|
|
60
|
-
const sync_rules = await this.collectSyncRules(baseConfig,
|
|
96
|
+
const sync_rules = await this.collectSyncRules(baseConfig, runnerConfig);
|
|
61
97
|
let jwt_audiences = baseConfig.client_auth?.audience ?? [];
|
|
62
98
|
let config = {
|
|
63
99
|
connection: mapped[0],
|
|
@@ -89,24 +125,13 @@ export class CompoundConfigCollector {
|
|
|
89
125
|
return config;
|
|
90
126
|
}
|
|
91
127
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
128
|
+
* Perform any additional resolving from {@link ResolvedPowerSyncConfig}
|
|
129
|
+
* to the extended {@link Generics['RESOLVED']}
|
|
130
|
+
*
|
|
94
131
|
*/
|
|
95
|
-
async
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const baseConfig = await collector.collect(runner_config);
|
|
99
|
-
if (baseConfig) {
|
|
100
|
-
return baseConfig;
|
|
101
|
-
}
|
|
102
|
-
logger.debug(`Could not collect PowerSync config with ${collector.name} method. Moving on to next method if available.`);
|
|
103
|
-
}
|
|
104
|
-
catch (ex) {
|
|
105
|
-
// An error in a collector is a hard stop
|
|
106
|
-
throw new Error(`Could not collect config using ${collector.name} method. Caught exception: ${ex}`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
throw new Error('PowerSyncConfig could not be collected using any of the registered config collectors.');
|
|
132
|
+
async resolveConfig(baseConfig, resolvedBaseConfig, runnerConfig = {}) {
|
|
133
|
+
// The base version has ResolvedPowerSyncConfig == Generics['RESOLVED']
|
|
134
|
+
return resolvedBaseConfig;
|
|
110
135
|
}
|
|
111
136
|
async collectSyncRules(baseConfig, runnerConfig) {
|
|
112
137
|
for (const collector of this.options.syncRulesCollectors) {
|
|
@@ -126,5 +151,27 @@ export class CompoundConfigCollector {
|
|
|
126
151
|
present: false
|
|
127
152
|
};
|
|
128
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Validates input config
|
|
156
|
+
* ts-codec itself doesn't give great validation errors, so we use json schema for that
|
|
157
|
+
*/
|
|
158
|
+
validate(config) {
|
|
159
|
+
// ts-codec itself doesn't give great validation errors, so we use json schema for that
|
|
160
|
+
const validator = schema
|
|
161
|
+
.parseJSONSchema(t.generateJSONSchema(this.codec, { allowAdditional: true, parsers: [configFile.portParser] }))
|
|
162
|
+
.validator();
|
|
163
|
+
const valid = validator.validate(config);
|
|
164
|
+
if (!valid.valid) {
|
|
165
|
+
throw new Error(`Failed to validate PowerSync config: ${valid.errors.join(', ')}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
decode(encoded) {
|
|
169
|
+
try {
|
|
170
|
+
return this.codec.decode(encoded);
|
|
171
|
+
}
|
|
172
|
+
catch (ex) {
|
|
173
|
+
throw new Error(`Failed to decode PowerSync config: ${ex}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
129
176
|
}
|
|
130
177
|
//# sourceMappingURL=compound-config-collector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compound-config-collector.js","sourceRoot":"","sources":["../../../src/util/config/compound-config-collector.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"compound-config-collector.js","sourceRoot":"","sources":["../../../src/util/config/compound-config-collector.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -5,16 +5,14 @@
|
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"version": "0.0.0-dev-
|
|
8
|
+
"version": "0.0.0-dev-20240718134716",
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"license": "FSL-1.1-Apache-2.0",
|
|
11
11
|
"type": "module",
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@js-sdsl/ordered-set": "^4.4.2",
|
|
14
14
|
"@opentelemetry/api": "~1.8.0",
|
|
15
|
-
"@opentelemetry/exporter-metrics-otlp-http": "^0.51.1",
|
|
16
15
|
"@opentelemetry/exporter-prometheus": "^0.51.1",
|
|
17
|
-
"@opentelemetry/resources": "^1.24.1",
|
|
18
16
|
"@opentelemetry/sdk-metrics": "1.24.1",
|
|
19
17
|
"async": "^3.2.4",
|
|
20
18
|
"async-mutex": "^0.5.0",
|
|
@@ -33,12 +31,12 @@
|
|
|
33
31
|
"uuid": "^9.0.1",
|
|
34
32
|
"winston": "^3.13.0",
|
|
35
33
|
"yaml": "^2.3.2",
|
|
36
|
-
"@powersync/lib-services-framework": "0.
|
|
34
|
+
"@powersync/lib-services-framework": "0.0.0-dev-20240718134716",
|
|
37
35
|
"@powersync/service-jpgwire": "0.17.13",
|
|
38
|
-
"@powersync/service-
|
|
39
|
-
"@powersync/service-
|
|
40
|
-
"@powersync/service-
|
|
41
|
-
"@powersync/service-
|
|
36
|
+
"@powersync/service-jsonbig": "0.17.10",
|
|
37
|
+
"@powersync/service-rsocket-router": "0.0.0-dev-20240718134716",
|
|
38
|
+
"@powersync/service-sync-rules": "0.18.1",
|
|
39
|
+
"@powersync/service-types": "0.1.0"
|
|
42
40
|
},
|
|
43
41
|
"devDependencies": {
|
|
44
42
|
"@types/async": "^3.2.24",
|
package/src/metrics/Metrics.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { Attributes, Counter, ObservableGauge, UpDownCounter, ValueType } from '@opentelemetry/api';
|
|
2
2
|
import { PrometheusExporter } from '@opentelemetry/exporter-prometheus';
|
|
3
|
-
import { MeterProvider
|
|
4
|
-
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
|
|
3
|
+
import { MeterProvider } from '@opentelemetry/sdk-metrics';
|
|
5
4
|
import * as jpgwire from '@powersync/service-jpgwire';
|
|
6
|
-
import * as util from '../util/util-index.js';
|
|
7
5
|
import * as storage from '../storage/storage-index.js';
|
|
8
6
|
import { CorePowerSyncSystem } from '../system/CorePowerSyncSystem.js';
|
|
9
|
-
import { Resource } from '@opentelemetry/resources';
|
|
10
7
|
import { logger } from '@powersync/lib-services-framework';
|
|
11
8
|
|
|
12
9
|
export interface MetricsOptions {
|
|
@@ -16,8 +13,6 @@ export interface MetricsOptions {
|
|
|
16
13
|
}
|
|
17
14
|
|
|
18
15
|
export class Metrics {
|
|
19
|
-
private static instance: Metrics;
|
|
20
|
-
|
|
21
16
|
private prometheusExporter: PrometheusExporter;
|
|
22
17
|
private meterProvider: MeterProvider;
|
|
23
18
|
|
|
@@ -60,7 +55,7 @@ export class Metrics {
|
|
|
60
55
|
// Record on API pod
|
|
61
56
|
public concurrent_connections: UpDownCounter<Attributes>;
|
|
62
57
|
|
|
63
|
-
|
|
58
|
+
constructor(meterProvider: MeterProvider, prometheusExporter: PrometheusExporter) {
|
|
64
59
|
this.meterProvider = meterProvider;
|
|
65
60
|
this.prometheusExporter = prometheusExporter;
|
|
66
61
|
const meter = meterProvider.getMeter('powersync');
|
|
@@ -132,66 +127,6 @@ export class Metrics {
|
|
|
132
127
|
this.concurrent_connections.add(0);
|
|
133
128
|
}
|
|
134
129
|
|
|
135
|
-
public static getInstance(): Metrics {
|
|
136
|
-
if (!Metrics.instance) {
|
|
137
|
-
throw new Error('Metrics have not been initialised');
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return Metrics.instance;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
public static async initialise(options: MetricsOptions): Promise<void> {
|
|
144
|
-
if (Metrics.instance) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
logger.info('Configuring telemetry.');
|
|
148
|
-
|
|
149
|
-
logger.info(
|
|
150
|
-
`
|
|
151
|
-
Attention:
|
|
152
|
-
PowerSync collects completely anonymous telemetry regarding usage.
|
|
153
|
-
This information is used to shape our roadmap to better serve our customers.
|
|
154
|
-
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
|
|
155
|
-
https://docs.powersync.com/self-hosting/telemetry
|
|
156
|
-
Anonymous telemetry is currently: ${options.disable_telemetry_sharing ? 'disabled' : 'enabled'}
|
|
157
|
-
`.trim()
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
const configuredExporters: MetricReader[] = [];
|
|
161
|
-
|
|
162
|
-
const port: number = util.env.METRICS_PORT ?? 0;
|
|
163
|
-
const prometheusExporter = new PrometheusExporter({ port: port, preventServerStart: true });
|
|
164
|
-
configuredExporters.push(prometheusExporter);
|
|
165
|
-
|
|
166
|
-
if (!options.disable_telemetry_sharing) {
|
|
167
|
-
logger.info('Sharing anonymous telemetry');
|
|
168
|
-
const periodicExporter = new PeriodicExportingMetricReader({
|
|
169
|
-
exporter: new OTLPMetricExporter({
|
|
170
|
-
url: options.internal_metrics_endpoint
|
|
171
|
-
}),
|
|
172
|
-
exportIntervalMillis: 1000 * 60 * 5 // 5 minutes
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
configuredExporters.push(periodicExporter);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
const meterProvider = new MeterProvider({
|
|
179
|
-
resource: new Resource({
|
|
180
|
-
['service']: 'PowerSync',
|
|
181
|
-
['instance_id']: options.powersync_instance_id
|
|
182
|
-
}),
|
|
183
|
-
readers: configuredExporters
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
if (port > 0) {
|
|
187
|
-
await prometheusExporter.startServer();
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
Metrics.instance = new Metrics(meterProvider, prometheusExporter);
|
|
191
|
-
|
|
192
|
-
logger.info('Telemetry configuration complete.');
|
|
193
|
-
}
|
|
194
|
-
|
|
195
130
|
public async shutdown(): Promise<void> {
|
|
196
131
|
await this.meterProvider.shutdown();
|
|
197
132
|
}
|