camusdb 0.6.0 → 0.7.0
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/README.md +193 -0
- package/dist/client.d.ts +42 -37
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +117 -166
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -1
- package/dist/endpoint-pool.d.ts +8 -0
- package/dist/endpoint-pool.d.ts.map +1 -1
- package/dist/endpoint-pool.js +25 -0
- package/dist/endpoint-pool.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/node-stats.d.ts +113 -0
- package/dist/node-stats.d.ts.map +1 -0
- package/dist/node-stats.js +90 -0
- package/dist/node-stats.js.map +1 -0
- package/dist/options.d.ts +10 -0
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +1 -0
- package/dist/options.js.map +1 -1
- package/dist/pipeline.d.ts +126 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +363 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/prepared/auto-prepare.d.ts +51 -0
- package/dist/prepared/auto-prepare.d.ts.map +1 -0
- package/dist/prepared/auto-prepare.js +150 -0
- package/dist/prepared/auto-prepare.js.map +1 -0
- package/dist/prepared/policy.d.ts +7 -0
- package/dist/prepared/policy.d.ts.map +1 -1
- package/dist/prepared/policy.js +16 -0
- package/dist/prepared/policy.js.map +1 -1
- package/dist/query-stream.d.ts +4 -1
- package/dist/query-stream.d.ts.map +1 -1
- package/dist/query-stream.js +13 -2
- package/dist/query-stream.js.map +1 -1
- package/dist/retry.d.ts +8 -0
- package/dist/retry.d.ts.map +1 -1
- package/dist/retry.js +12 -1
- package/dist/retry.js.map +1 -1
- package/dist/telemetry.d.ts +199 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +422 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/transaction.d.ts +60 -5
- package/dist/transaction.d.ts.map +1 -1
- package/dist/transaction.js +124 -24
- package/dist/transaction.js.map +1 -1
- package/dist/transport/authenticating-transport.d.ts +9 -1
- package/dist/transport/authenticating-transport.d.ts.map +1 -1
- package/dist/transport/authenticating-transport.js +13 -0
- package/dist/transport/authenticating-transport.js.map +1 -1
- package/dist/transport/grpc/batch-frames.d.ts +23 -5
- package/dist/transport/grpc/batch-frames.d.ts.map +1 -1
- package/dist/transport/grpc/batch-frames.js +29 -8
- package/dist/transport/grpc/batch-frames.js.map +1 -1
- package/dist/transport/grpc/batcher.d.ts +69 -5
- package/dist/transport/grpc/batcher.d.ts.map +1 -1
- package/dist/transport/grpc/batcher.js +217 -10
- package/dist/transport/grpc/batcher.js.map +1 -1
- package/dist/transport/grpc/grpc-transport.d.ts +35 -1
- package/dist/transport/grpc/grpc-transport.d.ts.map +1 -1
- package/dist/transport/grpc/grpc-transport.js +193 -7
- package/dist/transport/grpc/grpc-transport.js.map +1 -1
- package/dist/transport/grpc/messages.d.ts +15 -0
- package/dist/transport/grpc/messages.d.ts.map +1 -1
- package/dist/transport/grpc/messages.js +9 -0
- package/dist/transport/grpc/messages.js.map +1 -1
- package/dist/transport/rest-transport.d.ts +9 -1
- package/dist/transport/rest-transport.d.ts.map +1 -1
- package/dist/transport/rest-transport.js +24 -0
- package/dist/transport/rest-transport.js.map +1 -1
- package/dist/transport/sequential-pipeline.d.ts +21 -0
- package/dist/transport/sequential-pipeline.d.ts.map +1 -0
- package/dist/transport/sequential-pipeline.js +119 -0
- package/dist/transport/sequential-pipeline.js.map +1 -0
- package/dist/transport/transport.d.ts +94 -0
- package/dist/transport/transport.d.ts.map +1 -1
- package/dist/transport/transport.js +10 -0
- package/dist/transport/transport.js.map +1 -1
- package/package.json +10 -4
- package/proto/camus_sql.proto +114 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of CamusDB
|
|
3
|
+
*
|
|
4
|
+
* For the full copyright and license information, please view the LICENSE.txt
|
|
5
|
+
* file that was distributed with this source code.
|
|
6
|
+
*/
|
|
7
|
+
import { createRequire } from 'node:module';
|
|
8
|
+
import { CamusEndpointPool } from './endpoint-pool.js';
|
|
9
|
+
import { CamusError } from './errors.js';
|
|
10
|
+
import { CamusPreparedStatementPolicy } from './prepared/policy.js';
|
|
11
|
+
/**
|
|
12
|
+
* Traces and metrics through `@opentelemetry/api`.
|
|
13
|
+
*
|
|
14
|
+
* The package is an optional peer dependency, as the gRPC packages are. When it is installed, the
|
|
15
|
+
* driver reports through the global tracer and meter that it names `camusdb`. When it is not
|
|
16
|
+
* installed, every function here returns at once and the driver reports nothing. Install an
|
|
17
|
+
* OpenTelemetry SDK and register it as usual to collect the data. The driver needs no plugin.
|
|
18
|
+
*
|
|
19
|
+
* The span and metric names and attributes are those of the .NET driver, and they follow the
|
|
20
|
+
* OpenTelemetry database conventions. See the README for the list.
|
|
21
|
+
*/
|
|
22
|
+
/** The instrumentation scope that the driver's tracer and meter report under. */
|
|
23
|
+
export const CAMUS_TELEMETRY_NAME = 'camusdb';
|
|
24
|
+
/** The `db.system.name` of every span and measurement. */
|
|
25
|
+
const SYSTEM_NAME = 'camusdb';
|
|
26
|
+
/** The `camusdb.retry.kind` values: what the driver sent again. */
|
|
27
|
+
export const CamusRetryKind = {
|
|
28
|
+
/** A commit or a rollback sent again after `CADB0509`. */
|
|
29
|
+
Finalize: 'finalize',
|
|
30
|
+
/** A unit of work of `withRetry` run again after a serializable conflict. */
|
|
31
|
+
Autocommit: 'autocommit',
|
|
32
|
+
/** A unit of work of `client.transaction` run again, from `BEGIN`, after a serializable conflict. */
|
|
33
|
+
Transaction: 'transaction',
|
|
34
|
+
/** A call sent again with a new token after the server refused the old one. */
|
|
35
|
+
TokenRenewal: 'token_renewal',
|
|
36
|
+
/** A `CREATE DATABASE` or a branch creation sent again after a transient failure. */
|
|
37
|
+
CreateDatabase: 'create_database',
|
|
38
|
+
};
|
|
39
|
+
/** The `camusdb.prepared_statement.result` values. */
|
|
40
|
+
export const PreparedResult = {
|
|
41
|
+
Hit: 'hit',
|
|
42
|
+
Registered: 'registered',
|
|
43
|
+
Miss: 'miss',
|
|
44
|
+
Success: 'success',
|
|
45
|
+
Refused: 'refused',
|
|
46
|
+
Unsupported: 'unsupported',
|
|
47
|
+
};
|
|
48
|
+
// ─── Loading ────────────────────────────────────────────────────────────────
|
|
49
|
+
/** `undefined` until the first try, `null` when the package is not installed. */
|
|
50
|
+
let loadedApi;
|
|
51
|
+
let packageVersion;
|
|
52
|
+
/**
|
|
53
|
+
* The API, or `undefined` when the package is not installed.
|
|
54
|
+
*
|
|
55
|
+
* It is loaded with `require`, so the first operation is instrumented too: a dynamic `import` would
|
|
56
|
+
* leave every operation before it settles without a span. The API keeps its registrations in a
|
|
57
|
+
* process-wide global, so the copy that `require` loads sees the SDK that an ES module registered.
|
|
58
|
+
*/
|
|
59
|
+
function api() {
|
|
60
|
+
if (loadedApi === undefined) {
|
|
61
|
+
const require = createRequire(import.meta.url);
|
|
62
|
+
try {
|
|
63
|
+
loadedApi = require('@opentelemetry/api');
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
loadedApi = null;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
packageVersion = require('../package.json').version;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
packageVersion = undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return loadedApi ?? undefined;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* @internal Test hook: replaces the API, or with `null` plays a process without the package.
|
|
79
|
+
* `undefined` loads it again on the next operation.
|
|
80
|
+
*/
|
|
81
|
+
export function setTelemetryApi(replacement) {
|
|
82
|
+
loadedApi = replacement;
|
|
83
|
+
tracer = undefined;
|
|
84
|
+
instruments = undefined;
|
|
85
|
+
}
|
|
86
|
+
let tracer;
|
|
87
|
+
/** The global tracer. The API hands out a proxy, so a provider registered later still gets the spans. */
|
|
88
|
+
function tracerFor(otel) {
|
|
89
|
+
if (tracer?.api !== otel)
|
|
90
|
+
tracer = { api: otel, tracer: otel.trace.getTracer(CAMUS_TELEMETRY_NAME, packageVersion) };
|
|
91
|
+
return tracer.tracer;
|
|
92
|
+
}
|
|
93
|
+
let instruments;
|
|
94
|
+
/**
|
|
95
|
+
* The instruments, made on the meter of the current global provider.
|
|
96
|
+
*
|
|
97
|
+
* The metrics API has no proxy provider, so an instrument made before the SDK registered stays a
|
|
98
|
+
* no-op for good. The instruments are made again whenever the global provider changes.
|
|
99
|
+
*/
|
|
100
|
+
function instrumentsFor(otel) {
|
|
101
|
+
const provider = otel.metrics.getMeterProvider();
|
|
102
|
+
if (instruments?.api === otel && instruments.provider === provider)
|
|
103
|
+
return instruments;
|
|
104
|
+
const meter = otel.metrics.getMeter(CAMUS_TELEMETRY_NAME, packageVersion);
|
|
105
|
+
const quarantined = meter.createObservableGauge('camusdb.client.endpoint.quarantined', {
|
|
106
|
+
unit: '{endpoint}',
|
|
107
|
+
description: '1 while the endpoint is set aside after a transport failure, 0 while it takes traffic.',
|
|
108
|
+
});
|
|
109
|
+
quarantined.addCallback((result) => {
|
|
110
|
+
for (const [endpoint, isQuarantined] of CamusEndpointPool.collectQuarantine()) {
|
|
111
|
+
result.observe(isQuarantined ? 1 : 0, endpointAttributes(endpoint));
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
const preparedCount = meter.createObservableUpDownCounter('camusdb.client.prepared_statement.count', {
|
|
115
|
+
unit: '{statement}',
|
|
116
|
+
description: 'Statements kept prepared now.',
|
|
117
|
+
});
|
|
118
|
+
preparedCount.addCallback((result) => {
|
|
119
|
+
for (const [database, count] of CamusPreparedStatementPolicy.collectPreparedCounts()) {
|
|
120
|
+
result.observe(count, { 'db.namespace': database });
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
instruments = {
|
|
124
|
+
api: otel,
|
|
125
|
+
provider,
|
|
126
|
+
duration: meter.createHistogram('db.client.operation.duration', {
|
|
127
|
+
unit: 's',
|
|
128
|
+
description: 'Duration of database client operations.',
|
|
129
|
+
advice: { explicitBucketBoundaries: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10] },
|
|
130
|
+
}),
|
|
131
|
+
retries: meter.createCounter('camusdb.client.operation.retries', {
|
|
132
|
+
unit: '{retry}',
|
|
133
|
+
description: 'Operations the driver sent again after a failure it knows to be safe to retry.',
|
|
134
|
+
}),
|
|
135
|
+
quarantines: meter.createCounter('camusdb.client.endpoint.quarantines', {
|
|
136
|
+
unit: '{quarantine}',
|
|
137
|
+
description: 'Times an endpoint failed at the transport level and was set aside for 30 seconds.',
|
|
138
|
+
}),
|
|
139
|
+
lookups: meter.createCounter('camusdb.client.prepared_statement.lookups', {
|
|
140
|
+
unit: '{lookup}',
|
|
141
|
+
description: 'Executions of a preparable statement, by whether the statement went as a prepared handle.',
|
|
142
|
+
}),
|
|
143
|
+
registrations: meter.createCounter('camusdb.client.prepared_statement.registrations', {
|
|
144
|
+
unit: '{registration}',
|
|
145
|
+
description: 'Requests to the server to prepare a statement.',
|
|
146
|
+
}),
|
|
147
|
+
evictions: meter.createCounter('camusdb.client.prepared_statement.evictions', {
|
|
148
|
+
unit: '{eviction}',
|
|
149
|
+
description: 'Prepared statements released to make room for a statement used more recently.',
|
|
150
|
+
}),
|
|
151
|
+
};
|
|
152
|
+
return instruments;
|
|
153
|
+
}
|
|
154
|
+
/** The spans this driver started, so a retry adds its event only to one of them. */
|
|
155
|
+
const ownSpans = new WeakSet();
|
|
156
|
+
/**
|
|
157
|
+
* One instrumented operation: its span, and its start time for the duration histogram.
|
|
158
|
+
*
|
|
159
|
+
* It ends once. The first `complete` or `fail` ends it, and later calls do nothing.
|
|
160
|
+
*/
|
|
161
|
+
export class CamusOperation {
|
|
162
|
+
otel;
|
|
163
|
+
span;
|
|
164
|
+
startedAt;
|
|
165
|
+
database;
|
|
166
|
+
operationName;
|
|
167
|
+
ended = false;
|
|
168
|
+
serverAddress;
|
|
169
|
+
serverPort = 0;
|
|
170
|
+
/** @internal Use `startOperation`. */
|
|
171
|
+
constructor(otel, span, startedAt, database, operationName) {
|
|
172
|
+
this.otel = otel;
|
|
173
|
+
this.span = span;
|
|
174
|
+
this.startedAt = startedAt;
|
|
175
|
+
this.database = database;
|
|
176
|
+
this.operationName = operationName;
|
|
177
|
+
}
|
|
178
|
+
/** Records the server the operation goes to, as `server.address` and `server.port`. */
|
|
179
|
+
setEndpoint(endpoint) {
|
|
180
|
+
const { host, port } = parseEndpoint(endpoint);
|
|
181
|
+
this.serverAddress = host;
|
|
182
|
+
this.serverPort = port;
|
|
183
|
+
if (this.span.isRecording()) {
|
|
184
|
+
this.span.setAttribute('server.address', host);
|
|
185
|
+
if (port > 0)
|
|
186
|
+
this.span.setAttribute('server.port', port);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
setAttribute(key, value) {
|
|
190
|
+
if (this.span.isRecording())
|
|
191
|
+
this.span.setAttribute(key, value);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Runs `fn` with this operation's span as the active span, so the HTTP or gRPC spans of the
|
|
195
|
+
* transport are its children.
|
|
196
|
+
*/
|
|
197
|
+
run(fn) {
|
|
198
|
+
return this.otel.context.with(this.otel.trace.setSpan(this.otel.context.active(), this.span), fn);
|
|
199
|
+
}
|
|
200
|
+
/** Adds a `camusdb.retry` event to this operation's span. */
|
|
201
|
+
addRetryEvent(kind, errorType) {
|
|
202
|
+
this.span.addEvent('camusdb.retry', defined({ 'camusdb.retry.kind': kind, 'error.type': errorType }));
|
|
203
|
+
}
|
|
204
|
+
/** Ends the operation as a success. */
|
|
205
|
+
complete() {
|
|
206
|
+
this.end(undefined, false);
|
|
207
|
+
}
|
|
208
|
+
/** Ends the operation as a failure. */
|
|
209
|
+
fail(error) {
|
|
210
|
+
this.end(error, true);
|
|
211
|
+
}
|
|
212
|
+
end(error, failed) {
|
|
213
|
+
if (this.ended)
|
|
214
|
+
return;
|
|
215
|
+
this.ended = true;
|
|
216
|
+
// The conventions use the database status code as the error type when there is one.
|
|
217
|
+
const statusCode = failed && CamusError.is(error) ? error.code : undefined;
|
|
218
|
+
const errorType = failed ? (statusCode ?? errorTypeName(error)) : undefined;
|
|
219
|
+
if (failed) {
|
|
220
|
+
if (this.span.isRecording()) {
|
|
221
|
+
this.span.setAttribute('error.type', errorType);
|
|
222
|
+
if (statusCode !== undefined)
|
|
223
|
+
this.span.setAttribute('db.response.status_code', statusCode);
|
|
224
|
+
this.span.recordException(error instanceof Error ? error : String(error));
|
|
225
|
+
}
|
|
226
|
+
this.span.setStatus({
|
|
227
|
+
code: this.otel.SpanStatusCode.ERROR,
|
|
228
|
+
message: error instanceof Error ? error.message : String(error),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
this.span.end();
|
|
232
|
+
instrumentsFor(this.otel).duration.record((performance.now() - this.startedAt) / 1000, defined({
|
|
233
|
+
'db.system.name': SYSTEM_NAME,
|
|
234
|
+
'db.namespace': this.database,
|
|
235
|
+
'db.operation.name': this.operationName,
|
|
236
|
+
'server.address': this.serverAddress,
|
|
237
|
+
'server.port': this.serverPort > 0 ? this.serverPort : undefined,
|
|
238
|
+
'error.type': errorType,
|
|
239
|
+
'db.response.status_code': statusCode,
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Starts an operation, or reports `undefined` when `@opentelemetry/api` is not installed.
|
|
245
|
+
*
|
|
246
|
+
* The span is a child of the active span. Its name is `{operation} {target}`, where the target is
|
|
247
|
+
* the table when it is known, and the database if not.
|
|
248
|
+
*/
|
|
249
|
+
export function startOperation(scope, init) {
|
|
250
|
+
const otel = api();
|
|
251
|
+
if (otel === undefined)
|
|
252
|
+
return undefined;
|
|
253
|
+
const database = scope.database;
|
|
254
|
+
const target = init.collection ?? database;
|
|
255
|
+
const name = init.operationName === undefined ? target : `${init.operationName} ${target}`;
|
|
256
|
+
const span = tracerFor(otel).startSpan(name, { kind: otel.SpanKind.CLIENT }, otel.context.active());
|
|
257
|
+
ownSpans.add(span);
|
|
258
|
+
if (span.isRecording()) {
|
|
259
|
+
span.setAttribute('db.system.name', SYSTEM_NAME);
|
|
260
|
+
span.setAttribute('db.namespace', database);
|
|
261
|
+
if (init.operationName !== undefined)
|
|
262
|
+
span.setAttribute('db.operation.name', init.operationName);
|
|
263
|
+
if (init.collection !== undefined)
|
|
264
|
+
span.setAttribute('db.collection.name', init.collection);
|
|
265
|
+
if (init.batchSize !== undefined && init.batchSize > 0) {
|
|
266
|
+
span.setAttribute('db.operation.batch.size', init.batchSize);
|
|
267
|
+
}
|
|
268
|
+
if (init.queryText !== undefined && scope.config.traceQueryText) {
|
|
269
|
+
span.setAttribute('db.query.text', init.queryText);
|
|
270
|
+
}
|
|
271
|
+
span.setAttribute('camusdb.transport', scope.config.protocol);
|
|
272
|
+
}
|
|
273
|
+
return new CamusOperation(otel, span, performance.now(), database, init.operationName);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Runs one operation under a span, and ends the span with the operation's outcome.
|
|
277
|
+
*
|
|
278
|
+
* Without `@opentelemetry/api`, it only calls `run`.
|
|
279
|
+
*/
|
|
280
|
+
export async function traced(scope, init, run) {
|
|
281
|
+
const operation = startOperation(scope, init);
|
|
282
|
+
if (operation === undefined)
|
|
283
|
+
return run(undefined);
|
|
284
|
+
try {
|
|
285
|
+
const result = await operation.run(() => run(operation));
|
|
286
|
+
operation.complete();
|
|
287
|
+
return result;
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
operation.fail(error);
|
|
291
|
+
throw error;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* The statement verbs that become `db.operation.name`. A first keyword that is not in this list
|
|
296
|
+
* gives no operation name, so the metric keeps a small set of values.
|
|
297
|
+
*/
|
|
298
|
+
const KNOWN_OPERATIONS = new Set([
|
|
299
|
+
'SELECT',
|
|
300
|
+
'INSERT',
|
|
301
|
+
'UPDATE',
|
|
302
|
+
'DELETE',
|
|
303
|
+
'CREATE',
|
|
304
|
+
'ALTER',
|
|
305
|
+
'DROP',
|
|
306
|
+
'TRUNCATE',
|
|
307
|
+
'EXPLAIN',
|
|
308
|
+
'SHOW',
|
|
309
|
+
'REFRESH',
|
|
310
|
+
'COMMENT',
|
|
311
|
+
'GRANT',
|
|
312
|
+
'REVOKE',
|
|
313
|
+
'SET',
|
|
314
|
+
]);
|
|
315
|
+
/**
|
|
316
|
+
* The operation name of a statement: its first keyword in upper case when that keyword is a known
|
|
317
|
+
* verb, and `undefined` if not. Leading white space and opening parentheses are skipped.
|
|
318
|
+
*/
|
|
319
|
+
export function operationName(sql) {
|
|
320
|
+
const match = /^[\s(]*([A-Za-z]+)/.exec(sql);
|
|
321
|
+
const keyword = match?.[1]?.toUpperCase();
|
|
322
|
+
return keyword !== undefined && KNOWN_OPERATIONS.has(keyword) ? keyword : undefined;
|
|
323
|
+
}
|
|
324
|
+
// ─── Driver metrics ─────────────────────────────────────────────────────────
|
|
325
|
+
/**
|
|
326
|
+
* Counts one retry, and adds a `camusdb.retry` event to the driver span of the operation, or to the
|
|
327
|
+
* active span when it is one of the driver's.
|
|
328
|
+
*/
|
|
329
|
+
export function recordRetry(kind, error, details = {}) {
|
|
330
|
+
const otel = api();
|
|
331
|
+
if (otel === undefined)
|
|
332
|
+
return;
|
|
333
|
+
const errorType = CamusError.is(error) ? error.code : errorTypeName(error);
|
|
334
|
+
if (details.operation !== undefined) {
|
|
335
|
+
details.operation.addRetryEvent(kind, errorType);
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
const active = otel.trace.getActiveSpan();
|
|
339
|
+
if (active !== undefined && ownSpans.has(active)) {
|
|
340
|
+
active.addEvent('camusdb.retry', defined({ 'camusdb.retry.kind': kind, 'error.type': errorType }));
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
instrumentsFor(otel).retries.add(1, defined({
|
|
344
|
+
'camusdb.retry.kind': kind,
|
|
345
|
+
'error.type': errorType,
|
|
346
|
+
'db.namespace': details.database,
|
|
347
|
+
'db.operation.name': details.operationName,
|
|
348
|
+
}));
|
|
349
|
+
}
|
|
350
|
+
/** Counts one endpoint set aside after a transport failure. */
|
|
351
|
+
export function recordQuarantine(endpoint) {
|
|
352
|
+
const otel = api();
|
|
353
|
+
if (otel === undefined)
|
|
354
|
+
return;
|
|
355
|
+
instrumentsFor(otel).quarantines.add(1, endpointAttributes(endpoint));
|
|
356
|
+
}
|
|
357
|
+
/** Counts one execution of a preparable statement: `hit`, `registered`, or `miss`. */
|
|
358
|
+
export function recordPreparedLookup(database, result) {
|
|
359
|
+
const otel = api();
|
|
360
|
+
if (otel === undefined)
|
|
361
|
+
return;
|
|
362
|
+
instrumentsFor(otel).lookups.add(1, {
|
|
363
|
+
'db.namespace': database,
|
|
364
|
+
'camusdb.prepared_statement.result': result,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
/** Counts one request to prepare a statement: `success`, `refused`, or `unsupported`. */
|
|
368
|
+
export function recordPreparedRegistration(database, result, error) {
|
|
369
|
+
const otel = api();
|
|
370
|
+
if (otel === undefined)
|
|
371
|
+
return;
|
|
372
|
+
instrumentsFor(otel).registrations.add(1, defined({
|
|
373
|
+
'db.namespace': database,
|
|
374
|
+
'camusdb.prepared_statement.result': result,
|
|
375
|
+
'error.type': error === undefined ? undefined : CamusError.is(error) ? error.code : errorTypeName(error),
|
|
376
|
+
}));
|
|
377
|
+
}
|
|
378
|
+
/** Counts one prepared statement released to make room for one used more recently. */
|
|
379
|
+
export function recordPreparedEviction(database) {
|
|
380
|
+
const otel = api();
|
|
381
|
+
if (otel === undefined)
|
|
382
|
+
return;
|
|
383
|
+
instrumentsFor(otel).evictions.add(1, { 'db.namespace': database });
|
|
384
|
+
}
|
|
385
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
386
|
+
/** The parsed host and port of each endpoint. Endpoints come from configuration, so the map stays small. */
|
|
387
|
+
const parsedEndpoints = new Map();
|
|
388
|
+
function parseEndpoint(endpoint) {
|
|
389
|
+
let parsed = parsedEndpoints.get(endpoint);
|
|
390
|
+
if (parsed === undefined) {
|
|
391
|
+
try {
|
|
392
|
+
const url = new URL(endpoint);
|
|
393
|
+
const port = url.port.length > 0 ? Number(url.port) : url.protocol === 'https:' ? 443 : 80;
|
|
394
|
+
parsed = { host: url.hostname, port };
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
parsed = { host: endpoint, port: 0 };
|
|
398
|
+
}
|
|
399
|
+
if (parsedEndpoints.size < 1024)
|
|
400
|
+
parsedEndpoints.set(endpoint, parsed);
|
|
401
|
+
}
|
|
402
|
+
return parsed;
|
|
403
|
+
}
|
|
404
|
+
function endpointAttributes(endpoint) {
|
|
405
|
+
const { host, port } = parseEndpoint(endpoint);
|
|
406
|
+
return port > 0 ? { 'server.address': host, 'server.port': port } : { 'server.address': host };
|
|
407
|
+
}
|
|
408
|
+
/** The attributes without the keys whose value is unknown. The SDK warns about an `undefined` value. */
|
|
409
|
+
function defined(attributes) {
|
|
410
|
+
const result = {};
|
|
411
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
412
|
+
if (value !== undefined)
|
|
413
|
+
result[key] = value;
|
|
414
|
+
}
|
|
415
|
+
return result;
|
|
416
|
+
}
|
|
417
|
+
function errorTypeName(error) {
|
|
418
|
+
if (error instanceof Error)
|
|
419
|
+
return error.name.length > 0 ? error.name : 'Error';
|
|
420
|
+
return '_OTHER';
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
|
package/dist/transaction.d.ts
CHANGED
|
@@ -5,7 +5,19 @@
|
|
|
5
5
|
* file that was distributed with this source code.
|
|
6
6
|
*/
|
|
7
7
|
import type { CamusTransactionOptions } from './options.js';
|
|
8
|
+
import { CamusPipeline } from './pipeline.js';
|
|
8
9
|
import type { ClientRuntime } from './runtime.js';
|
|
10
|
+
import type { StartTransactionResult } from './transport/transport.js';
|
|
11
|
+
/**
|
|
12
|
+
* A pipeline's claim on a transaction's `BEGIN`. It is settled once the server answered the
|
|
13
|
+
* `BEGIN` that rode the pipeline's exchange.
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export interface StartClaim {
|
|
18
|
+
resolve(result: StartTransactionResult, target: string): void;
|
|
19
|
+
reject(error: Error): void;
|
|
20
|
+
}
|
|
9
21
|
/**
|
|
10
22
|
* A set of reads and writes that take effect atomically, at one logical instant, across columns,
|
|
11
23
|
* rows, and tables.
|
|
@@ -18,9 +30,13 @@ import type { ClientRuntime } from './runtime.js';
|
|
|
18
30
|
* a later transaction, but never relocates this one. A caller that knows the transaction's hot
|
|
19
31
|
* statement can choose the endpoint at `BEGIN` with `options.affinity` instead.
|
|
20
32
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
33
|
+
* `options.deferBegin` defers `BEGIN` with learned routing off too. The first statement then starts
|
|
34
|
+
* the transaction on the pool's rotation. When that first statement is a `CamusPipeline` send, the
|
|
35
|
+
* `BEGIN` travels inside the same exchange.
|
|
36
|
+
*
|
|
37
|
+
* Two consequences of the deferral are visible, and only for a deferred transaction: the
|
|
38
|
+
* server-minted identity reads as zero until the first statement, and a failure to begin surfaces
|
|
39
|
+
* from that first statement rather than from the call that created the transaction.
|
|
24
40
|
*/
|
|
25
41
|
export declare class CamusTransaction {
|
|
26
42
|
private readonly runtime;
|
|
@@ -37,6 +53,11 @@ export declare class CamusTransaction {
|
|
|
37
53
|
private startPromise;
|
|
38
54
|
private startFailed;
|
|
39
55
|
private finalized;
|
|
56
|
+
/**
|
|
57
|
+
* True once a pipeline committed this transaction, so that a later finalize does not ask the
|
|
58
|
+
* server about a transaction it no longer knows.
|
|
59
|
+
*/
|
|
60
|
+
private committedByPipeline;
|
|
40
61
|
/** The concurrency knobs this transaction was begun with, after every default was applied. */
|
|
41
62
|
readonly options: CamusTransactionOptions;
|
|
42
63
|
/**
|
|
@@ -54,8 +75,8 @@ export declare class CamusTransaction {
|
|
|
54
75
|
/**
|
|
55
76
|
* True once the server minted this transaction.
|
|
56
77
|
*
|
|
57
|
-
* It is always true with learned routing off
|
|
58
|
-
* statement, or until an explicit `affinity`, starts it.
|
|
78
|
+
* It is always true with learned routing off and no `deferBegin`. For a deferred transaction it
|
|
79
|
+
* is false until the first statement, or until an explicit `affinity`, starts it.
|
|
59
80
|
*/
|
|
60
81
|
get isStarted(): boolean;
|
|
61
82
|
/** True once this transaction was committed or rolled back. */
|
|
@@ -80,6 +101,40 @@ export declare class CamusTransaction {
|
|
|
80
101
|
*/
|
|
81
102
|
ensureStarted(preferredEndpoint: string | undefined, signal?: AbortSignal): Promise<string>;
|
|
82
103
|
private startOn;
|
|
104
|
+
private seat;
|
|
105
|
+
/**
|
|
106
|
+
* Several statements of this transaction, sent as one exchange and answered together. See
|
|
107
|
+
* `CamusPipeline`. A transaction begun with `deferBegin`, or with learned routing on, sends its
|
|
108
|
+
* `BEGIN` inside the first pipeline send too.
|
|
109
|
+
*/
|
|
110
|
+
pipeline(): CamusPipeline;
|
|
111
|
+
/**
|
|
112
|
+
* Lets a pipeline begin this transaction inside its first exchange.
|
|
113
|
+
*
|
|
114
|
+
* When nothing has begun the transaction yet, it reports a claim. The pipeline settles the claim
|
|
115
|
+
* after the server answered the `BEGIN`. When a `BEGIN` is already under way, it reports that
|
|
116
|
+
* `BEGIN` for the pipeline to await instead. When the transaction has started, it reports
|
|
117
|
+
* neither. The memoized `startPromise` is what makes a pipeline and a statement that race to be
|
|
118
|
+
* the first one agree on one `BEGIN`.
|
|
119
|
+
*
|
|
120
|
+
* @internal
|
|
121
|
+
*/
|
|
122
|
+
claimStart(): {
|
|
123
|
+
claim?: StartClaim;
|
|
124
|
+
pending?: Promise<void>;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Records that a pipeline's conditional commit committed this transaction.
|
|
128
|
+
*
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
markCommittedByPipeline(): void;
|
|
132
|
+
/**
|
|
133
|
+
* True when a pipeline committed this transaction.
|
|
134
|
+
*
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
137
|
+
get isCommittedByPipeline(): boolean;
|
|
83
138
|
/** Makes this transaction's writes durable. */
|
|
84
139
|
commit(signal?: AbortSignal): Promise<void>;
|
|
85
140
|
/** Discards this transaction's writes. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9D,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IAExC,OAAO,CAAC,YAAY,CAAM;IAE1B,OAAO,CAAC,iBAAiB,CAAK;IAE9B,OAAO,CAAC,aAAa,CAAqB;IAE1C,OAAO,CAAC,YAAY,CAAS;IAE7B;;;;;OAKG;IACH,OAAO,CAAC,YAAY,CAA4B;IAEhD,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,SAAS,CAAS;IAE1B;;;OAGG;IACH,OAAO,CAAC,mBAAmB,CAAS;IAEpC,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAE1C;;;OAGG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAE/B,oDAAoD;gBAElD,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,uBAAuB,EAChC,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;IAcxG;;;;;OAKG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,+DAA+D;IAC/D,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,+FAA+F;IAC/F,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,yFAAyF;IACzF,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,4DAA4D;IAC5D,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,2FAA2F;IAC3F,IAAI,QAAQ,IAAI,MAAM,GAAG,SAAS,CAEjC;IAED;;;;;;;;;OASG;IACG,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;YAUnF,OAAO;IAqBrB,OAAO,CAAC,IAAI;IAQZ;;;;OAIG;IACH,QAAQ,IAAI,aAAa;IAIzB;;;;;;;;;;OAUG;IACH,UAAU,IAAI;QAAE,KAAK,CAAC,EAAE,UAAU,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE;IAiC7D;;;;OAIG;IACH,uBAAuB,IAAI,IAAI;IAK/B;;;;OAIG;IACH,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAED,+CAA+C;IAC/C,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C;;;;;;;;;;OAUG;YACW,QAAQ;IAmEtB;;;;OAIG;IACG,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5C;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,CAAC,SAAS;;;MAAoB;CAC9C"}
|