@milaboratories/pl-client 2.7.0 → 2.7.2
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/dist/core/client.d.ts +9 -0
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/config.d.ts +3 -3
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/stat.d.ts +36 -0
- package/dist/core/stat.d.ts.map +1 -0
- package/dist/core/transaction.d.ts +2 -0
- package/dist/core/transaction.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1343 -1250
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
- package/src/core/client.ts +35 -1
- package/src/core/config.ts +3 -3
- package/src/core/stat.ts +102 -0
- package/src/core/transaction.ts +54 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-client",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"description": "New TS/JS client for Platform API",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,21 +17,21 @@
|
|
|
17
17
|
"./src/**/*"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@grpc/grpc-js": "^1.12.
|
|
20
|
+
"@grpc/grpc-js": "^1.12.5",
|
|
21
21
|
"@protobuf-ts/grpc-transport": "^2.9.4",
|
|
22
22
|
"@protobuf-ts/runtime": "^2.9.4",
|
|
23
23
|
"@protobuf-ts/runtime-rpc": "^2.9.4",
|
|
24
24
|
"canonicalize": "^2.0.0",
|
|
25
25
|
"denque": "^2.1.0",
|
|
26
26
|
"lru-cache": "^11.0.2",
|
|
27
|
-
"https-proxy-agent": "^7.0.
|
|
27
|
+
"https-proxy-agent": "^7.0.6",
|
|
28
28
|
"cacheable-lookup": "^6.1.0",
|
|
29
29
|
"long": "^5.2.3",
|
|
30
|
-
"undici": "^7.
|
|
30
|
+
"undici": "^7.2.0",
|
|
31
31
|
"utility-types": "^3.11.0",
|
|
32
32
|
"yaml": "^2.6.1",
|
|
33
|
-
"@milaboratories/
|
|
34
|
-
"@milaboratories/
|
|
33
|
+
"@milaboratories/pl-http": "^1.0.2",
|
|
34
|
+
"@milaboratories/ts-helpers": "^1.1.3"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"typescript": "~5.5.4",
|
package/src/core/client.ts
CHANGED
|
@@ -23,6 +23,7 @@ import { Dispatcher } from 'undici';
|
|
|
23
23
|
import { LRUCache } from 'lru-cache';
|
|
24
24
|
import { ResourceDataCacheRecord } from './cache';
|
|
25
25
|
import { DefaultFinalResourceDataPredicate, FinalResourceDataPredicate } from './final';
|
|
26
|
+
import { addStat, AllTxStat, initialTxStat, TxStat } from './stat';
|
|
26
27
|
|
|
27
28
|
export type TxOps = PlCallOps & {
|
|
28
29
|
sync?: boolean;
|
|
@@ -59,6 +60,10 @@ export class PlClient {
|
|
|
59
60
|
|
|
60
61
|
private _serverInfo: MaintenanceAPI_Ping_Response | undefined = undefined;
|
|
61
62
|
|
|
63
|
+
private _txCommittedStat: TxStat = initialTxStat();
|
|
64
|
+
private _txConflictStat: TxStat = initialTxStat();
|
|
65
|
+
private _txErrorStat: TxStat = initialTxStat();
|
|
66
|
+
|
|
62
67
|
//
|
|
63
68
|
// Caching
|
|
64
69
|
//
|
|
@@ -110,6 +115,30 @@ export class PlClient {
|
|
|
110
115
|
}
|
|
111
116
|
}
|
|
112
117
|
|
|
118
|
+
public get txCommittedStat(): TxStat {
|
|
119
|
+
return { ...this._txCommittedStat };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public get txConflictStat(): TxStat {
|
|
123
|
+
return { ...this._txConflictStat };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public get txErrorStat(): TxStat {
|
|
127
|
+
return { ...this._txErrorStat };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public get txTotalStat(): TxStat {
|
|
131
|
+
return addStat(addStat(this._txCommittedStat, this._txConflictStat), this._txErrorStat);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public get allTxStat(): AllTxStat {
|
|
135
|
+
return {
|
|
136
|
+
committed: this.txCommittedStat,
|
|
137
|
+
conflict: this.txConflictStat,
|
|
138
|
+
error: this.txErrorStat
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
113
142
|
public async ping(): Promise<MaintenanceAPI_Ping_Response> {
|
|
114
143
|
return (await this.ll.grpcPl.ping({})).response;
|
|
115
144
|
}
|
|
@@ -234,13 +263,18 @@ export class PlClient {
|
|
|
234
263
|
try {
|
|
235
264
|
// executing transaction body
|
|
236
265
|
result = await body(tx);
|
|
266
|
+
// collecting stat
|
|
267
|
+
this._txCommittedStat = addStat(this._txCommittedStat, tx.stat);
|
|
237
268
|
ok = true;
|
|
238
269
|
} catch (e: unknown) {
|
|
239
270
|
// the only recoverable
|
|
240
271
|
if (e instanceof TxCommitConflict) {
|
|
241
272
|
// ignoring
|
|
242
|
-
//
|
|
273
|
+
// collecting stat
|
|
274
|
+
this._txConflictStat = addStat(this._txConflictStat, tx.stat);
|
|
243
275
|
} else {
|
|
276
|
+
// collecting stat
|
|
277
|
+
this._txErrorStat = addStat(this._txErrorStat, tx.stat);
|
|
244
278
|
throw e;
|
|
245
279
|
}
|
|
246
280
|
} finally {
|
package/src/core/config.ts
CHANGED
|
@@ -87,9 +87,9 @@ export const DEFAULT_AUTH_MAX_REFRESH = 12 * 24 * 60 * 60;
|
|
|
87
87
|
export const DEFAULT_MAX_CACHE_BYTES = 128_000_000; // 128 Mb
|
|
88
88
|
|
|
89
89
|
export const DEFAULT_RETRY_BACKOFF_ALGORITHM = 'exponential';
|
|
90
|
-
export const DEFAULT_RETRY_MAX_ATTEMPTS =
|
|
91
|
-
export const DEFAULT_RETRY_INITIAL_DELAY =
|
|
92
|
-
export const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER =
|
|
90
|
+
export const DEFAULT_RETRY_MAX_ATTEMPTS = 16; // 1st attempt + 15 retries
|
|
91
|
+
export const DEFAULT_RETRY_INITIAL_DELAY = 14; // 14 ms * <jitter> of sleep after first failure
|
|
92
|
+
export const DEFAULT_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER = 1.5; // + 50% on each round
|
|
93
93
|
export const DEFAULT_RETRY_LINEAR_BACKOFF_STEP = 50; // + 50 ms
|
|
94
94
|
export const DEFAULT_RETRY_JITTER = 0.3; // 30%
|
|
95
95
|
|
package/src/core/stat.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export type TxStat = {
|
|
2
|
+
txCount: number;
|
|
3
|
+
|
|
4
|
+
rootsCreated: number;
|
|
5
|
+
structsCreated: number;
|
|
6
|
+
structsCreatedDataBytes: number;
|
|
7
|
+
ephemeralsCreated: number;
|
|
8
|
+
ephemeralsCreatedDataBytes: number;
|
|
9
|
+
valuesCreated: number;
|
|
10
|
+
valuesCreatedDataBytes: number;
|
|
11
|
+
|
|
12
|
+
kvSetRequests: number;
|
|
13
|
+
kvSetBytes: number;
|
|
14
|
+
|
|
15
|
+
inputsLocked: number;
|
|
16
|
+
outputsLocked: number;
|
|
17
|
+
fieldsCreated: number;
|
|
18
|
+
fieldsSet: number;
|
|
19
|
+
fieldsGet: number;
|
|
20
|
+
|
|
21
|
+
rGetDataCacheHits: number;
|
|
22
|
+
rGetDataCacheFields: number;
|
|
23
|
+
rGetDataCacheBytes: number;
|
|
24
|
+
rGetDataNetRequests: number;
|
|
25
|
+
rGetDataNetFields: number;
|
|
26
|
+
rGetDataNetBytes: number;
|
|
27
|
+
|
|
28
|
+
kvListRequests: number;
|
|
29
|
+
kvListEntries: number;
|
|
30
|
+
kvListBytes: number;
|
|
31
|
+
|
|
32
|
+
kvGetRequests: number;
|
|
33
|
+
kvGetBytes: number;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export function initialTxStat(): TxStat {
|
|
37
|
+
return {
|
|
38
|
+
txCount: 0,
|
|
39
|
+
rootsCreated: 0,
|
|
40
|
+
structsCreated: 0,
|
|
41
|
+
structsCreatedDataBytes: 0,
|
|
42
|
+
ephemeralsCreated: 0,
|
|
43
|
+
ephemeralsCreatedDataBytes: 0,
|
|
44
|
+
valuesCreated: 0,
|
|
45
|
+
valuesCreatedDataBytes: 0,
|
|
46
|
+
kvSetRequests: 0,
|
|
47
|
+
kvSetBytes: 0,
|
|
48
|
+
inputsLocked: 0,
|
|
49
|
+
outputsLocked: 0,
|
|
50
|
+
fieldsCreated: 0,
|
|
51
|
+
fieldsSet: 0,
|
|
52
|
+
fieldsGet: 0,
|
|
53
|
+
rGetDataCacheHits: 0,
|
|
54
|
+
rGetDataCacheFields: 0,
|
|
55
|
+
rGetDataCacheBytes: 0,
|
|
56
|
+
rGetDataNetRequests: 0,
|
|
57
|
+
rGetDataNetFields: 0,
|
|
58
|
+
rGetDataNetBytes: 0,
|
|
59
|
+
kvListRequests: 0,
|
|
60
|
+
kvListEntries: 0,
|
|
61
|
+
kvListBytes: 0,
|
|
62
|
+
kvGetRequests: 0,
|
|
63
|
+
kvGetBytes: 0
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function addStat(a: TxStat, b: TxStat): TxStat {
|
|
68
|
+
return {
|
|
69
|
+
txCount: a.txCount + b.txCount,
|
|
70
|
+
rootsCreated: a.rootsCreated + b.rootsCreated,
|
|
71
|
+
structsCreated: a.structsCreated + b.structsCreated,
|
|
72
|
+
structsCreatedDataBytes: a.structsCreatedDataBytes + b.structsCreatedDataBytes,
|
|
73
|
+
ephemeralsCreated: a.ephemeralsCreated + b.ephemeralsCreated,
|
|
74
|
+
ephemeralsCreatedDataBytes: a.ephemeralsCreatedDataBytes + b.ephemeralsCreatedDataBytes,
|
|
75
|
+
valuesCreated: a.valuesCreated + b.valuesCreated,
|
|
76
|
+
valuesCreatedDataBytes: a.valuesCreatedDataBytes + b.valuesCreatedDataBytes,
|
|
77
|
+
kvSetRequests: a.kvSetRequests + b.kvSetRequests,
|
|
78
|
+
kvSetBytes: a.kvSetBytes + b.kvSetBytes,
|
|
79
|
+
inputsLocked: a.inputsLocked + b.inputsLocked,
|
|
80
|
+
outputsLocked: a.outputsLocked + b.outputsLocked,
|
|
81
|
+
fieldsCreated: a.fieldsCreated + b.fieldsCreated,
|
|
82
|
+
fieldsSet: a.fieldsSet + b.fieldsSet,
|
|
83
|
+
fieldsGet: a.fieldsGet + b.fieldsGet,
|
|
84
|
+
rGetDataCacheHits: a.rGetDataCacheHits + b.rGetDataCacheHits,
|
|
85
|
+
rGetDataCacheFields: a.rGetDataCacheFields + b.rGetDataCacheFields,
|
|
86
|
+
rGetDataCacheBytes: a.rGetDataCacheBytes + b.rGetDataCacheBytes,
|
|
87
|
+
rGetDataNetRequests: a.rGetDataNetRequests + b.rGetDataNetRequests,
|
|
88
|
+
rGetDataNetFields: a.rGetDataNetFields + b.rGetDataNetFields,
|
|
89
|
+
rGetDataNetBytes: a.rGetDataNetBytes + b.rGetDataNetBytes,
|
|
90
|
+
kvListRequests: a.kvListRequests + b.kvListRequests,
|
|
91
|
+
kvListEntries: a.kvListEntries + b.kvListEntries,
|
|
92
|
+
kvListBytes: a.kvListBytes + b.kvListBytes,
|
|
93
|
+
kvGetRequests: a.kvGetRequests + b.kvGetRequests,
|
|
94
|
+
kvGetBytes: a.kvGetBytes + b.kvGetBytes
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type AllTxStat = {
|
|
99
|
+
committed: TxStat;
|
|
100
|
+
conflict: TxStat;
|
|
101
|
+
error: TxStat;
|
|
102
|
+
};
|
package/src/core/transaction.ts
CHANGED
|
@@ -30,6 +30,7 @@ import { isNotFoundError } from './errors';
|
|
|
30
30
|
import { FinalResourceDataPredicate } from './final';
|
|
31
31
|
import { LRUCache } from 'lru-cache';
|
|
32
32
|
import { ResourceDataCacheRecord } from './cache';
|
|
33
|
+
import { initialTxStat, TxStat } from './stat';
|
|
33
34
|
|
|
34
35
|
/** Reference to resource, used only within transaction */
|
|
35
36
|
export interface ResourceRef {
|
|
@@ -154,6 +155,8 @@ export class PlTransaction {
|
|
|
154
155
|
|
|
155
156
|
private globalTxIdWasAwaited: boolean = false;
|
|
156
157
|
|
|
158
|
+
public readonly stat: TxStat = initialTxStat();
|
|
159
|
+
|
|
157
160
|
constructor(
|
|
158
161
|
private readonly ll: LLPlTransaction,
|
|
159
162
|
public readonly name: string,
|
|
@@ -182,6 +185,9 @@ export class PlTransaction {
|
|
|
182
185
|
console.warn(err);
|
|
183
186
|
}
|
|
184
187
|
});
|
|
188
|
+
|
|
189
|
+
// Adding stats
|
|
190
|
+
this.stat.txCount++;
|
|
185
191
|
}
|
|
186
192
|
|
|
187
193
|
private async drainAndAwaitPendingOps(): Promise<void> {
|
|
@@ -367,6 +373,7 @@ export class PlTransaction {
|
|
|
367
373
|
}
|
|
368
374
|
|
|
369
375
|
public createRoot(type: ResourceType): ResourceRef {
|
|
376
|
+
this.stat.rootsCreated++;
|
|
370
377
|
return this.createResource(
|
|
371
378
|
true,
|
|
372
379
|
(localId) => ({ oneofKind: 'resourceCreateRoot', resourceCreateRoot: { type, id: localId } }),
|
|
@@ -375,6 +382,8 @@ export class PlTransaction {
|
|
|
375
382
|
}
|
|
376
383
|
|
|
377
384
|
public createStruct(type: ResourceType, data?: Uint8Array | string): ResourceRef {
|
|
385
|
+
this.stat.structsCreated++;
|
|
386
|
+
this.stat.structsCreatedDataBytes += data?.length ?? 0;
|
|
378
387
|
return this.createResource(
|
|
379
388
|
false,
|
|
380
389
|
(localId) => ({
|
|
@@ -390,6 +399,8 @@ export class PlTransaction {
|
|
|
390
399
|
}
|
|
391
400
|
|
|
392
401
|
public createEphemeral(type: ResourceType, data?: Uint8Array | string): ResourceRef {
|
|
402
|
+
this.stat.ephemeralsCreated++;
|
|
403
|
+
this.stat.ephemeralsCreatedDataBytes += data?.length ?? 0;
|
|
393
404
|
return this.createResource(
|
|
394
405
|
false,
|
|
395
406
|
(localId) => ({
|
|
@@ -409,6 +420,8 @@ export class PlTransaction {
|
|
|
409
420
|
data: Uint8Array | string,
|
|
410
421
|
errorIfExists: boolean = false
|
|
411
422
|
): ResourceRef {
|
|
423
|
+
this.stat.valuesCreated++;
|
|
424
|
+
this.stat.valuesCreatedDataBytes += data?.length ?? 0;
|
|
412
425
|
return this.createResource(
|
|
413
426
|
false,
|
|
414
427
|
(localId) => ({
|
|
@@ -496,8 +509,16 @@ export class PlTransaction {
|
|
|
496
509
|
// checking if we can return result from cache
|
|
497
510
|
const fromCache = this.sharedResourceDataCache.get(rId);
|
|
498
511
|
if (fromCache && fromCache.cacheTxOpenTimestamp < this.txOpenTimestamp) {
|
|
499
|
-
if (!loadFields)
|
|
500
|
-
|
|
512
|
+
if (!loadFields) {
|
|
513
|
+
this.stat.rGetDataCacheHits++;
|
|
514
|
+
this.stat.rGetDataCacheBytes += fromCache.basicData.data?.length ?? 0;
|
|
515
|
+
return fromCache.basicData;
|
|
516
|
+
} else if (fromCache.data) {
|
|
517
|
+
this.stat.rGetDataCacheHits++;
|
|
518
|
+
this.stat.rGetDataCacheBytes += fromCache.basicData.data?.length ?? 0;
|
|
519
|
+
this.stat.rGetDataCacheFields += fromCache.data.fields.length;
|
|
520
|
+
return fromCache.data;
|
|
521
|
+
}
|
|
501
522
|
}
|
|
502
523
|
}
|
|
503
524
|
|
|
@@ -509,6 +530,10 @@ export class PlTransaction {
|
|
|
509
530
|
(r) => protoToResource(notEmpty(r.resourceGet.resource))
|
|
510
531
|
);
|
|
511
532
|
|
|
533
|
+
this.stat.rGetDataNetRequests++;
|
|
534
|
+
this.stat.rGetDataNetBytes += result.data?.length ?? 0;
|
|
535
|
+
this.stat.rGetDataNetFields += result.fields.length;
|
|
536
|
+
|
|
512
537
|
// we will cache only final resource data states
|
|
513
538
|
// caching result even if we were ignore the cache
|
|
514
539
|
if (!isResourceRef(rId) && !isLocalResourceId(rId) && this.finalPredicate(result)) {
|
|
@@ -575,6 +600,7 @@ export class PlTransaction {
|
|
|
575
600
|
* have their values, if inputs list is not locked.
|
|
576
601
|
*/
|
|
577
602
|
public lockInputs(rId: AnyResourceRef): void {
|
|
603
|
+
this.stat.inputsLocked++;
|
|
578
604
|
this.sendVoidAsync({
|
|
579
605
|
oneofKind: 'resourceLockInputs',
|
|
580
606
|
resourceLockInputs: { resourceId: toResourceId(rId) }
|
|
@@ -586,6 +612,7 @@ export class PlTransaction {
|
|
|
586
612
|
* This is required for resource to pass deduplication.
|
|
587
613
|
*/
|
|
588
614
|
public lockOutputs(rId: AnyResourceRef): void {
|
|
615
|
+
this.stat.outputsLocked++;
|
|
589
616
|
this.sendVoidAsync({
|
|
590
617
|
oneofKind: 'resourceLockOutputs',
|
|
591
618
|
resourceLockOutputs: { resourceId: toResourceId(rId) }
|
|
@@ -602,6 +629,7 @@ export class PlTransaction {
|
|
|
602
629
|
//
|
|
603
630
|
|
|
604
631
|
public createField(fId: AnyFieldRef, fieldType: FieldType, value?: AnyRef): void {
|
|
632
|
+
this.stat.fieldsCreated++;
|
|
605
633
|
this.sendVoidAsync({
|
|
606
634
|
oneofKind: 'fieldCreate',
|
|
607
635
|
fieldCreate: { type: fieldTypeToProto(fieldType), id: toFieldId(fId) }
|
|
@@ -620,6 +648,7 @@ export class PlTransaction {
|
|
|
620
648
|
}
|
|
621
649
|
|
|
622
650
|
public setField(fId: AnyFieldRef, ref: AnyRef): void {
|
|
651
|
+
this.stat.fieldsSet++;
|
|
623
652
|
if (isResource(ref))
|
|
624
653
|
this.sendVoidAsync({
|
|
625
654
|
oneofKind: 'fieldSet',
|
|
@@ -642,6 +671,7 @@ export class PlTransaction {
|
|
|
642
671
|
}
|
|
643
672
|
|
|
644
673
|
public setFieldError(fId: AnyFieldRef, ref: AnyResourceRef): void {
|
|
674
|
+
this.stat.fieldsSet++;
|
|
645
675
|
this.sendVoidAsync({
|
|
646
676
|
oneofKind: 'fieldSetError',
|
|
647
677
|
fieldSetError: { field: toFieldId(fId), errResourceId: toResourceId(ref) }
|
|
@@ -649,6 +679,7 @@ export class PlTransaction {
|
|
|
649
679
|
}
|
|
650
680
|
|
|
651
681
|
public async getField(fId: AnyFieldRef): Promise<FieldData> {
|
|
682
|
+
this.stat.fieldsGet++;
|
|
652
683
|
return await this.sendSingleAndParse(
|
|
653
684
|
{ oneofKind: 'fieldGet', fieldGet: { field: toFieldId(fId) } },
|
|
654
685
|
(r) => protoToField(notEmpty(r.fieldGet.field))
|
|
@@ -672,13 +703,19 @@ export class PlTransaction {
|
|
|
672
703
|
//
|
|
673
704
|
|
|
674
705
|
public async listKeyValues(rId: AnyResourceRef): Promise<KeyValue[]> {
|
|
675
|
-
|
|
706
|
+
const result = await this.sendMultiAndParse(
|
|
676
707
|
{
|
|
677
708
|
oneofKind: 'resourceKeyValueList',
|
|
678
709
|
resourceKeyValueList: { resourceId: toResourceId(rId), startFrom: '', limit: 0 }
|
|
679
710
|
},
|
|
680
711
|
(r) => r.map((e) => e.resourceKeyValueList.record!)
|
|
681
712
|
);
|
|
713
|
+
|
|
714
|
+
this.stat.kvListRequests++;
|
|
715
|
+
this.stat.kvListEntries += result.length;
|
|
716
|
+
for (const kv of result) this.stat.kvListBytes += kv.key.length + kv.value.length;
|
|
717
|
+
|
|
718
|
+
return result;
|
|
682
719
|
}
|
|
683
720
|
|
|
684
721
|
public async listKeyValuesString(rId: AnyResourceRef): Promise<KeyValueString[]> {
|
|
@@ -699,6 +736,8 @@ export class PlTransaction {
|
|
|
699
736
|
}
|
|
700
737
|
|
|
701
738
|
public setKValue(rId: AnyResourceRef, key: string, value: Uint8Array | string): void {
|
|
739
|
+
this.stat.kvSetRequests++;
|
|
740
|
+
this.stat.kvSetBytes++;
|
|
702
741
|
this.sendVoidAsync({
|
|
703
742
|
oneofKind: 'resourceKeyValueSet',
|
|
704
743
|
resourceKeyValueSet: {
|
|
@@ -720,13 +759,18 @@ export class PlTransaction {
|
|
|
720
759
|
}
|
|
721
760
|
|
|
722
761
|
public async getKValue(rId: AnyResourceRef, key: string): Promise<Uint8Array> {
|
|
723
|
-
|
|
762
|
+
const result = await this.sendSingleAndParse(
|
|
724
763
|
{
|
|
725
764
|
oneofKind: 'resourceKeyValueGet',
|
|
726
765
|
resourceKeyValueGet: { resourceId: toResourceId(rId), key }
|
|
727
766
|
},
|
|
728
767
|
(r) => r.resourceKeyValueGet.value
|
|
729
768
|
);
|
|
769
|
+
|
|
770
|
+
this.stat.kvGetRequests++;
|
|
771
|
+
this.stat.kvGetBytes += result.length;
|
|
772
|
+
|
|
773
|
+
return result;
|
|
730
774
|
}
|
|
731
775
|
|
|
732
776
|
public async getKValueString(rId: AnyResourceRef, key: string): Promise<string> {
|
|
@@ -741,7 +785,7 @@ export class PlTransaction {
|
|
|
741
785
|
rId: AnyResourceRef,
|
|
742
786
|
key: string
|
|
743
787
|
): Promise<Uint8Array | undefined> {
|
|
744
|
-
|
|
788
|
+
const result = await this.sendSingleAndParse(
|
|
745
789
|
{
|
|
746
790
|
oneofKind: 'resourceKeyValueGetIfExists',
|
|
747
791
|
resourceKeyValueGetIfExists: { resourceId: toResourceId(rId), key }
|
|
@@ -749,6 +793,11 @@ export class PlTransaction {
|
|
|
749
793
|
(r) =>
|
|
750
794
|
r.resourceKeyValueGetIfExists.exists ? r.resourceKeyValueGetIfExists.value : undefined
|
|
751
795
|
);
|
|
796
|
+
|
|
797
|
+
this.stat.kvGetRequests++;
|
|
798
|
+
this.stat.kvGetBytes += result?.length ?? 0;
|
|
799
|
+
|
|
800
|
+
return result;
|
|
752
801
|
}
|
|
753
802
|
|
|
754
803
|
public async getKValueStringIfExists(
|