@fjell/registry 4.4.10 → 4.4.11
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/Registry.cjs +36 -3
- package/dist/Registry.js +36 -3
- package/dist/RegistryStats.cjs +200 -0
- package/dist/RegistryStats.d.ts +103 -0
- package/dist/RegistryStats.js +196 -0
- package/dist/index.cjs +229 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/dist/types.d.ts +7 -0
- package/docs/README.md +5 -5
- package/docs/index.html +1 -1
- package/docs/memory-data/scaling-10-instances.json +206 -206
- package/docs/memory-data/scaling-100-instances.json +206 -206
- package/docs/memory-data/scaling-1000-instances.json +108 -108
- package/docs/memory-data/scaling-10000-instances.json +49 -49
- package/docs/memory-data/scaling-20-instances.json +208 -208
- package/docs/memory-data/scaling-200-instances.json +206 -206
- package/docs/memory-data/scaling-2000-instances.json +109 -109
- package/docs/memory-data/scaling-50-instances.json +206 -206
- package/docs/memory-data/scaling-500-instances.json +108 -108
- package/docs/memory-data/scaling-5000-instances.json +49 -49
- package/docs/memory-overhead.svg +16 -16
- package/docs/memory.md +122 -122
- package/docs/public/package.json +65 -0
- package/docs/src/App.css +84 -22
- package/docs/src/App.tsx +39 -16
- package/docs/src/index.css +1 -7
- package/docs/timing-range.svg +38 -40
- package/docs/timing.md +122 -122
- package/examples/README.md +19 -0
- package/examples/registry-statistics-example.ts +264 -0
- package/package.json +1 -1
package/dist/Registry.cjs
CHANGED
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
5
5
|
const logger$1 = require('./logger.cjs');
|
|
6
6
|
const Instance = require('./Instance.cjs');
|
|
7
7
|
const Coordinate = require('./Coordinate.cjs');
|
|
8
|
+
const RegistryStats = require('./RegistryStats.cjs');
|
|
8
9
|
|
|
9
10
|
const logger = logger$1.default.get("Registry");
|
|
10
11
|
const findScopedInstance = (scopedInstances, requestedScopes)=>{
|
|
@@ -29,13 +30,39 @@ const findScopedInstance = (scopedInstances, requestedScopes)=>{
|
|
|
29
30
|
};
|
|
30
31
|
const createRegistry = (type, registryHub)=>{
|
|
31
32
|
const instanceTree = {};
|
|
33
|
+
// Statistics tracking
|
|
34
|
+
const registryStats = new RegistryStats.RegistryStats();
|
|
35
|
+
/**
|
|
36
|
+
* Creates a proxied Registry that automatically injects client information for service-to-service calls
|
|
37
|
+
*/ const createProxiedRegistry = (callingCoordinate)=>{
|
|
38
|
+
const serviceClient = {
|
|
39
|
+
registryType: type,
|
|
40
|
+
coordinate: {
|
|
41
|
+
kta: callingCoordinate.kta,
|
|
42
|
+
scopes: callingCoordinate.scopes
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
...registry,
|
|
47
|
+
get: (kta, options)=>{
|
|
48
|
+
// Automatically inject the calling service as the client if no client is specified
|
|
49
|
+
const clientToUse = (options === null || options === void 0 ? void 0 : options.client) || serviceClient;
|
|
50
|
+
return registry.get(kta, {
|
|
51
|
+
...options,
|
|
52
|
+
client: clientToUse
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
};
|
|
32
57
|
const createInstance = (kta, scopes, factory)=>{
|
|
33
58
|
logger.debug(`Creating and registering instance for key path and scopes`, kta, scopes, `in registry type: ${type}`);
|
|
34
59
|
// Create coordinate for the instance
|
|
35
60
|
const coordinate = Coordinate.createCoordinate(kta, scopes);
|
|
36
|
-
//
|
|
61
|
+
// Create a proxied registry that automatically tracks this service as the client
|
|
62
|
+
const proxiedRegistry = createProxiedRegistry(coordinate);
|
|
63
|
+
// Use factory to create the instance with the proxied registry
|
|
37
64
|
const instance = factory(coordinate, {
|
|
38
|
-
registry,
|
|
65
|
+
registry: proxiedRegistry,
|
|
39
66
|
registryHub
|
|
40
67
|
});
|
|
41
68
|
// Validate the created instance
|
|
@@ -87,6 +114,8 @@ const createRegistry = (type, registryHub)=>{
|
|
|
87
114
|
registerInternal(kta, instance, options);
|
|
88
115
|
};
|
|
89
116
|
const get = (kta, options)=>{
|
|
117
|
+
// Track statistics with kta, scopes, and client
|
|
118
|
+
registryStats.recordGetCall(kta, options === null || options === void 0 ? void 0 : options.scopes, options === null || options === void 0 ? void 0 : options.client);
|
|
90
119
|
const keyPath = [
|
|
91
120
|
...kta
|
|
92
121
|
].reverse();
|
|
@@ -133,6 +162,9 @@ const createRegistry = (type, registryHub)=>{
|
|
|
133
162
|
traverseTree(instanceTree);
|
|
134
163
|
return coordinates;
|
|
135
164
|
};
|
|
165
|
+
const getStatistics = ()=>{
|
|
166
|
+
return registryStats.getStatistics();
|
|
167
|
+
};
|
|
136
168
|
const registry = {
|
|
137
169
|
type,
|
|
138
170
|
registryHub,
|
|
@@ -140,10 +172,11 @@ const createRegistry = (type, registryHub)=>{
|
|
|
140
172
|
register,
|
|
141
173
|
get,
|
|
142
174
|
getCoordinates,
|
|
175
|
+
getStatistics,
|
|
143
176
|
instanceTree
|
|
144
177
|
};
|
|
145
178
|
return registry;
|
|
146
179
|
};
|
|
147
180
|
|
|
148
181
|
exports.createRegistry = createRegistry;
|
|
149
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,
|
|
182
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnkuY2pzIiwic291cmNlcyI6W10sInNvdXJjZXNDb250ZW50IjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=
|
package/dist/Registry.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import LibLogger from './logger.js';
|
|
2
2
|
import { isInstance } from './Instance.js';
|
|
3
3
|
import { createCoordinate } from './Coordinate.js';
|
|
4
|
+
import { RegistryStats } from './RegistryStats.js';
|
|
4
5
|
|
|
5
6
|
const logger = LibLogger.get("Registry");
|
|
6
7
|
const findScopedInstance = (scopedInstances, requestedScopes)=>{
|
|
@@ -25,13 +26,39 @@ const findScopedInstance = (scopedInstances, requestedScopes)=>{
|
|
|
25
26
|
};
|
|
26
27
|
const createRegistry = (type, registryHub)=>{
|
|
27
28
|
const instanceTree = {};
|
|
29
|
+
// Statistics tracking
|
|
30
|
+
const registryStats = new RegistryStats();
|
|
31
|
+
/**
|
|
32
|
+
* Creates a proxied Registry that automatically injects client information for service-to-service calls
|
|
33
|
+
*/ const createProxiedRegistry = (callingCoordinate)=>{
|
|
34
|
+
const serviceClient = {
|
|
35
|
+
registryType: type,
|
|
36
|
+
coordinate: {
|
|
37
|
+
kta: callingCoordinate.kta,
|
|
38
|
+
scopes: callingCoordinate.scopes
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
...registry,
|
|
43
|
+
get: (kta, options)=>{
|
|
44
|
+
// Automatically inject the calling service as the client if no client is specified
|
|
45
|
+
const clientToUse = (options === null || options === void 0 ? void 0 : options.client) || serviceClient;
|
|
46
|
+
return registry.get(kta, {
|
|
47
|
+
...options,
|
|
48
|
+
client: clientToUse
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
};
|
|
28
53
|
const createInstance = (kta, scopes, factory)=>{
|
|
29
54
|
logger.debug(`Creating and registering instance for key path and scopes`, kta, scopes, `in registry type: ${type}`);
|
|
30
55
|
// Create coordinate for the instance
|
|
31
56
|
const coordinate = createCoordinate(kta, scopes);
|
|
32
|
-
//
|
|
57
|
+
// Create a proxied registry that automatically tracks this service as the client
|
|
58
|
+
const proxiedRegistry = createProxiedRegistry(coordinate);
|
|
59
|
+
// Use factory to create the instance with the proxied registry
|
|
33
60
|
const instance = factory(coordinate, {
|
|
34
|
-
registry,
|
|
61
|
+
registry: proxiedRegistry,
|
|
35
62
|
registryHub
|
|
36
63
|
});
|
|
37
64
|
// Validate the created instance
|
|
@@ -83,6 +110,8 @@ const createRegistry = (type, registryHub)=>{
|
|
|
83
110
|
registerInternal(kta, instance, options);
|
|
84
111
|
};
|
|
85
112
|
const get = (kta, options)=>{
|
|
113
|
+
// Track statistics with kta, scopes, and client
|
|
114
|
+
registryStats.recordGetCall(kta, options === null || options === void 0 ? void 0 : options.scopes, options === null || options === void 0 ? void 0 : options.client);
|
|
86
115
|
const keyPath = [
|
|
87
116
|
...kta
|
|
88
117
|
].reverse();
|
|
@@ -129,6 +158,9 @@ const createRegistry = (type, registryHub)=>{
|
|
|
129
158
|
traverseTree(instanceTree);
|
|
130
159
|
return coordinates;
|
|
131
160
|
};
|
|
161
|
+
const getStatistics = ()=>{
|
|
162
|
+
return registryStats.getStatistics();
|
|
163
|
+
};
|
|
132
164
|
const registry = {
|
|
133
165
|
type,
|
|
134
166
|
registryHub,
|
|
@@ -136,10 +168,11 @@ const createRegistry = (type, registryHub)=>{
|
|
|
136
168
|
register,
|
|
137
169
|
get,
|
|
138
170
|
getCoordinates,
|
|
171
|
+
getStatistics,
|
|
139
172
|
instanceTree
|
|
140
173
|
};
|
|
141
174
|
return registry;
|
|
142
175
|
};
|
|
143
176
|
|
|
144
177
|
export { createRegistry };
|
|
145
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,
|
|
178
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnkuanMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OyJ9
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents a service client (another service making the request)
|
|
7
|
+
*/ function _define_property(obj, key, value) {
|
|
8
|
+
if (key in obj) {
|
|
9
|
+
Object.defineProperty(obj, key, {
|
|
10
|
+
value: value,
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
writable: true
|
|
14
|
+
});
|
|
15
|
+
} else {
|
|
16
|
+
obj[key] = value;
|
|
17
|
+
}
|
|
18
|
+
return obj;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Internal class for tracking Registry statistics with complex coordinate combinations and client tracking
|
|
22
|
+
*/ class RegistryStats {
|
|
23
|
+
/**
|
|
24
|
+
* Records a get() call for the specified coordinate and client
|
|
25
|
+
*/ recordGetCall(kta, scopes, client) {
|
|
26
|
+
this.totalCalls++;
|
|
27
|
+
const ktaKey = kta.join('.');
|
|
28
|
+
const scopeKey = this.createScopeKey(scopes || []);
|
|
29
|
+
const clientKey = this.createClientKey(client);
|
|
30
|
+
if (!this.coordinateCalls.has(ktaKey)) {
|
|
31
|
+
this.coordinateCalls.set(ktaKey, new Map());
|
|
32
|
+
}
|
|
33
|
+
const scopeMap = this.coordinateCalls.get(ktaKey);
|
|
34
|
+
if (!scopeMap.has(scopeKey)) {
|
|
35
|
+
scopeMap.set(scopeKey, new Map());
|
|
36
|
+
}
|
|
37
|
+
const clientMap = scopeMap.get(scopeKey);
|
|
38
|
+
const currentCount = clientMap.get(clientKey) || 0;
|
|
39
|
+
clientMap.set(clientKey, currentCount + 1);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Gets the current statistics snapshot
|
|
43
|
+
*/ getStatistics() {
|
|
44
|
+
const coordinateCallRecords = [];
|
|
45
|
+
let serviceCalls = 0;
|
|
46
|
+
let applicationCalls = 0;
|
|
47
|
+
let unidentifiedCalls = 0;
|
|
48
|
+
for (const [ktaKey, scopeMap] of this.coordinateCalls){
|
|
49
|
+
for (const [scopeKey, clientMap] of scopeMap){
|
|
50
|
+
const clientCalls = [];
|
|
51
|
+
let totalCount = 0;
|
|
52
|
+
for (const [clientKey, count] of clientMap){
|
|
53
|
+
const client = this.parseClientKey(clientKey);
|
|
54
|
+
if (client !== null) {
|
|
55
|
+
clientCalls.push({
|
|
56
|
+
client,
|
|
57
|
+
count
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
totalCount += count;
|
|
61
|
+
// Update client summary
|
|
62
|
+
if (clientKey === '__no_client__') {
|
|
63
|
+
unidentifiedCalls += count;
|
|
64
|
+
} else if (typeof client === 'string') {
|
|
65
|
+
applicationCalls += count;
|
|
66
|
+
} else if (client !== null) {
|
|
67
|
+
serviceCalls += count;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
coordinateCallRecords.push({
|
|
71
|
+
kta: ktaKey.split('.'),
|
|
72
|
+
scopes: this.parseScopeKey(scopeKey),
|
|
73
|
+
count: totalCount,
|
|
74
|
+
clientCalls: [
|
|
75
|
+
...clientCalls
|
|
76
|
+
] // Return a copy
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
totalGetCalls: this.totalCalls,
|
|
82
|
+
coordinateCallRecords: [
|
|
83
|
+
...coordinateCallRecords
|
|
84
|
+
],
|
|
85
|
+
clientSummary: {
|
|
86
|
+
serviceCalls,
|
|
87
|
+
applicationCalls,
|
|
88
|
+
unidentifiedCalls
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Gets call count for a specific coordinate combination
|
|
94
|
+
*/ getCallCount(kta, scopes) {
|
|
95
|
+
const ktaKey = kta.join('.');
|
|
96
|
+
const scopeKey = this.createScopeKey(scopes || []);
|
|
97
|
+
const scopeMap = this.coordinateCalls.get(ktaKey);
|
|
98
|
+
if (!scopeMap) return 0;
|
|
99
|
+
const clientMap = scopeMap.get(scopeKey);
|
|
100
|
+
if (!clientMap) return 0;
|
|
101
|
+
let total = 0;
|
|
102
|
+
for (const count of clientMap.values()){
|
|
103
|
+
total += count;
|
|
104
|
+
}
|
|
105
|
+
return total;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Gets call count for a specific coordinate combination from a specific client
|
|
109
|
+
*/ getCallCountByClient(kta, scopes, client) {
|
|
110
|
+
const ktaKey = kta.join('.');
|
|
111
|
+
const scopeKey = this.createScopeKey(scopes || []);
|
|
112
|
+
const clientKey = this.createClientKey(client);
|
|
113
|
+
const scopeMap = this.coordinateCalls.get(ktaKey);
|
|
114
|
+
if (!scopeMap) return 0;
|
|
115
|
+
const clientMap = scopeMap.get(scopeKey);
|
|
116
|
+
if (!clientMap) return 0;
|
|
117
|
+
return clientMap.get(clientKey) || 0;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Gets total calls for a specific kta (across all scopes)
|
|
121
|
+
*/ getTotalCallsForKta(kta) {
|
|
122
|
+
const ktaKey = kta.join('.');
|
|
123
|
+
const scopeMap = this.coordinateCalls.get(ktaKey);
|
|
124
|
+
if (!scopeMap) return 0;
|
|
125
|
+
let total = 0;
|
|
126
|
+
for (const clientMap of scopeMap.values()){
|
|
127
|
+
for (const count of clientMap.values()){
|
|
128
|
+
total += count;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return total;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Gets all unique kta paths that have been called
|
|
135
|
+
*/ getCalledKtaPaths() {
|
|
136
|
+
const ktaPaths = [];
|
|
137
|
+
for (const ktaKey of this.coordinateCalls.keys()){
|
|
138
|
+
ktaPaths.push(ktaKey.split('.'));
|
|
139
|
+
}
|
|
140
|
+
return ktaPaths;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Creates a normalized scope key from scopes array
|
|
144
|
+
*/ createScopeKey(scopes) {
|
|
145
|
+
if (scopes.length === 0) return '__no_scopes__';
|
|
146
|
+
return [
|
|
147
|
+
...scopes
|
|
148
|
+
].sort().join(',');
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Parses a scope key back to scopes array
|
|
152
|
+
*/ parseScopeKey(scopeKey) {
|
|
153
|
+
if (scopeKey === '__no_scopes__') return [];
|
|
154
|
+
return scopeKey.split(',');
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Creates a normalized client key from client identifier
|
|
158
|
+
*/ createClientKey(client) {
|
|
159
|
+
if (!client) return '__no_client__';
|
|
160
|
+
if (typeof client === 'string') {
|
|
161
|
+
return `app:${client}`;
|
|
162
|
+
}
|
|
163
|
+
// Service client
|
|
164
|
+
const coordKey = `${client.coordinate.kta.join('.')};${this.createScopeKey(client.coordinate.scopes)}`;
|
|
165
|
+
return `service:${client.registryType}:${coordKey}`;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Parses a client key back to client identifier
|
|
169
|
+
*/ parseClientKey(clientKey) {
|
|
170
|
+
if (clientKey === '__no_client__') return null;
|
|
171
|
+
if (clientKey.startsWith('app:')) {
|
|
172
|
+
return clientKey.substring(4);
|
|
173
|
+
}
|
|
174
|
+
if (clientKey.startsWith('service:')) {
|
|
175
|
+
const parts = clientKey.substring(8).split(':');
|
|
176
|
+
if (parts.length !== 2) return null;
|
|
177
|
+
const registryType = parts[0];
|
|
178
|
+
const coordParts = parts[1].split(';');
|
|
179
|
+
if (coordParts.length !== 2) return null;
|
|
180
|
+
const kta = coordParts[0].split('.');
|
|
181
|
+
const scopes = this.parseScopeKey(coordParts[1]);
|
|
182
|
+
return {
|
|
183
|
+
registryType,
|
|
184
|
+
coordinate: {
|
|
185
|
+
kta,
|
|
186
|
+
scopes
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
constructor(){
|
|
193
|
+
_define_property(this, "totalCalls", 0);
|
|
194
|
+
// Map structure: ktaKey -> scopeKey -> clientKey -> count
|
|
195
|
+
_define_property(this, "coordinateCalls", new Map());
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
exports.RegistryStats = RegistryStats;
|
|
200
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnlTdGF0cy5janMiLCJzb3VyY2VzIjpbXSwic291cmNlc0NvbnRlbnQiOltdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OzsifQ==
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a service client (another service making the request)
|
|
3
|
+
*/
|
|
4
|
+
export interface ServiceClient {
|
|
5
|
+
/** The type of registry where the calling service is registered */
|
|
6
|
+
registryType: string;
|
|
7
|
+
/** The coordinate of the calling service */
|
|
8
|
+
coordinate: {
|
|
9
|
+
kta: string[];
|
|
10
|
+
scopes: string[];
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Represents either a service or application client
|
|
15
|
+
*/
|
|
16
|
+
export type ClientIdentifier = ServiceClient | string;
|
|
17
|
+
/**
|
|
18
|
+
* Represents a specific coordinate call with both kta and scopes
|
|
19
|
+
*/
|
|
20
|
+
export interface CoordinateCallRecord {
|
|
21
|
+
/** The key type array that was requested */
|
|
22
|
+
kta: string[];
|
|
23
|
+
/** The scopes that were requested (empty array if no scopes) */
|
|
24
|
+
scopes: string[];
|
|
25
|
+
/** Number of times this exact combination was called */
|
|
26
|
+
count: number;
|
|
27
|
+
/** Breakdown of calls by client */
|
|
28
|
+
clientCalls: ClientCallRecord[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Represents calls from a specific client
|
|
32
|
+
*/
|
|
33
|
+
export interface ClientCallRecord {
|
|
34
|
+
/** The client that made the calls */
|
|
35
|
+
client: ClientIdentifier;
|
|
36
|
+
/** Number of calls from this client */
|
|
37
|
+
count: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Statistics about Registry get() method calls with detailed coordinate tracking
|
|
41
|
+
*/
|
|
42
|
+
export interface RegistryStatistics {
|
|
43
|
+
/** Total number of get() calls made on this registry */
|
|
44
|
+
totalGetCalls: number;
|
|
45
|
+
/** Detailed records of each unique coordinate combination and their call counts */
|
|
46
|
+
coordinateCallRecords: CoordinateCallRecord[];
|
|
47
|
+
/** Summary of calls by client type */
|
|
48
|
+
clientSummary: {
|
|
49
|
+
/** Total calls from services (service-to-service) */
|
|
50
|
+
serviceCalls: number;
|
|
51
|
+
/** Total calls from applications (direct application calls) */
|
|
52
|
+
applicationCalls: number;
|
|
53
|
+
/** Total calls with no client specified */
|
|
54
|
+
unidentifiedCalls: number;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Internal class for tracking Registry statistics with complex coordinate combinations and client tracking
|
|
59
|
+
*/
|
|
60
|
+
export declare class RegistryStats {
|
|
61
|
+
private totalCalls;
|
|
62
|
+
private coordinateCalls;
|
|
63
|
+
/**
|
|
64
|
+
* Records a get() call for the specified coordinate and client
|
|
65
|
+
*/
|
|
66
|
+
recordGetCall(kta: string[], scopes?: string[], client?: ClientIdentifier): void;
|
|
67
|
+
/**
|
|
68
|
+
* Gets the current statistics snapshot
|
|
69
|
+
*/
|
|
70
|
+
getStatistics(): RegistryStatistics;
|
|
71
|
+
/**
|
|
72
|
+
* Gets call count for a specific coordinate combination
|
|
73
|
+
*/
|
|
74
|
+
getCallCount(kta: string[], scopes?: string[]): number;
|
|
75
|
+
/**
|
|
76
|
+
* Gets call count for a specific coordinate combination from a specific client
|
|
77
|
+
*/
|
|
78
|
+
getCallCountByClient(kta: string[], scopes?: string[], client?: ClientIdentifier): number;
|
|
79
|
+
/**
|
|
80
|
+
* Gets total calls for a specific kta (across all scopes)
|
|
81
|
+
*/
|
|
82
|
+
getTotalCallsForKta(kta: string[]): number;
|
|
83
|
+
/**
|
|
84
|
+
* Gets all unique kta paths that have been called
|
|
85
|
+
*/
|
|
86
|
+
getCalledKtaPaths(): string[][];
|
|
87
|
+
/**
|
|
88
|
+
* Creates a normalized scope key from scopes array
|
|
89
|
+
*/
|
|
90
|
+
private createScopeKey;
|
|
91
|
+
/**
|
|
92
|
+
* Parses a scope key back to scopes array
|
|
93
|
+
*/
|
|
94
|
+
private parseScopeKey;
|
|
95
|
+
/**
|
|
96
|
+
* Creates a normalized client key from client identifier
|
|
97
|
+
*/
|
|
98
|
+
private createClientKey;
|
|
99
|
+
/**
|
|
100
|
+
* Parses a client key back to client identifier
|
|
101
|
+
*/
|
|
102
|
+
private parseClientKey;
|
|
103
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a service client (another service making the request)
|
|
3
|
+
*/ function _define_property(obj, key, value) {
|
|
4
|
+
if (key in obj) {
|
|
5
|
+
Object.defineProperty(obj, key, {
|
|
6
|
+
value: value,
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
writable: true
|
|
10
|
+
});
|
|
11
|
+
} else {
|
|
12
|
+
obj[key] = value;
|
|
13
|
+
}
|
|
14
|
+
return obj;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Internal class for tracking Registry statistics with complex coordinate combinations and client tracking
|
|
18
|
+
*/ class RegistryStats {
|
|
19
|
+
/**
|
|
20
|
+
* Records a get() call for the specified coordinate and client
|
|
21
|
+
*/ recordGetCall(kta, scopes, client) {
|
|
22
|
+
this.totalCalls++;
|
|
23
|
+
const ktaKey = kta.join('.');
|
|
24
|
+
const scopeKey = this.createScopeKey(scopes || []);
|
|
25
|
+
const clientKey = this.createClientKey(client);
|
|
26
|
+
if (!this.coordinateCalls.has(ktaKey)) {
|
|
27
|
+
this.coordinateCalls.set(ktaKey, new Map());
|
|
28
|
+
}
|
|
29
|
+
const scopeMap = this.coordinateCalls.get(ktaKey);
|
|
30
|
+
if (!scopeMap.has(scopeKey)) {
|
|
31
|
+
scopeMap.set(scopeKey, new Map());
|
|
32
|
+
}
|
|
33
|
+
const clientMap = scopeMap.get(scopeKey);
|
|
34
|
+
const currentCount = clientMap.get(clientKey) || 0;
|
|
35
|
+
clientMap.set(clientKey, currentCount + 1);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gets the current statistics snapshot
|
|
39
|
+
*/ getStatistics() {
|
|
40
|
+
const coordinateCallRecords = [];
|
|
41
|
+
let serviceCalls = 0;
|
|
42
|
+
let applicationCalls = 0;
|
|
43
|
+
let unidentifiedCalls = 0;
|
|
44
|
+
for (const [ktaKey, scopeMap] of this.coordinateCalls){
|
|
45
|
+
for (const [scopeKey, clientMap] of scopeMap){
|
|
46
|
+
const clientCalls = [];
|
|
47
|
+
let totalCount = 0;
|
|
48
|
+
for (const [clientKey, count] of clientMap){
|
|
49
|
+
const client = this.parseClientKey(clientKey);
|
|
50
|
+
if (client !== null) {
|
|
51
|
+
clientCalls.push({
|
|
52
|
+
client,
|
|
53
|
+
count
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
totalCount += count;
|
|
57
|
+
// Update client summary
|
|
58
|
+
if (clientKey === '__no_client__') {
|
|
59
|
+
unidentifiedCalls += count;
|
|
60
|
+
} else if (typeof client === 'string') {
|
|
61
|
+
applicationCalls += count;
|
|
62
|
+
} else if (client !== null) {
|
|
63
|
+
serviceCalls += count;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
coordinateCallRecords.push({
|
|
67
|
+
kta: ktaKey.split('.'),
|
|
68
|
+
scopes: this.parseScopeKey(scopeKey),
|
|
69
|
+
count: totalCount,
|
|
70
|
+
clientCalls: [
|
|
71
|
+
...clientCalls
|
|
72
|
+
] // Return a copy
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
totalGetCalls: this.totalCalls,
|
|
78
|
+
coordinateCallRecords: [
|
|
79
|
+
...coordinateCallRecords
|
|
80
|
+
],
|
|
81
|
+
clientSummary: {
|
|
82
|
+
serviceCalls,
|
|
83
|
+
applicationCalls,
|
|
84
|
+
unidentifiedCalls
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Gets call count for a specific coordinate combination
|
|
90
|
+
*/ getCallCount(kta, scopes) {
|
|
91
|
+
const ktaKey = kta.join('.');
|
|
92
|
+
const scopeKey = this.createScopeKey(scopes || []);
|
|
93
|
+
const scopeMap = this.coordinateCalls.get(ktaKey);
|
|
94
|
+
if (!scopeMap) return 0;
|
|
95
|
+
const clientMap = scopeMap.get(scopeKey);
|
|
96
|
+
if (!clientMap) return 0;
|
|
97
|
+
let total = 0;
|
|
98
|
+
for (const count of clientMap.values()){
|
|
99
|
+
total += count;
|
|
100
|
+
}
|
|
101
|
+
return total;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Gets call count for a specific coordinate combination from a specific client
|
|
105
|
+
*/ getCallCountByClient(kta, scopes, client) {
|
|
106
|
+
const ktaKey = kta.join('.');
|
|
107
|
+
const scopeKey = this.createScopeKey(scopes || []);
|
|
108
|
+
const clientKey = this.createClientKey(client);
|
|
109
|
+
const scopeMap = this.coordinateCalls.get(ktaKey);
|
|
110
|
+
if (!scopeMap) return 0;
|
|
111
|
+
const clientMap = scopeMap.get(scopeKey);
|
|
112
|
+
if (!clientMap) return 0;
|
|
113
|
+
return clientMap.get(clientKey) || 0;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Gets total calls for a specific kta (across all scopes)
|
|
117
|
+
*/ getTotalCallsForKta(kta) {
|
|
118
|
+
const ktaKey = kta.join('.');
|
|
119
|
+
const scopeMap = this.coordinateCalls.get(ktaKey);
|
|
120
|
+
if (!scopeMap) return 0;
|
|
121
|
+
let total = 0;
|
|
122
|
+
for (const clientMap of scopeMap.values()){
|
|
123
|
+
for (const count of clientMap.values()){
|
|
124
|
+
total += count;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return total;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Gets all unique kta paths that have been called
|
|
131
|
+
*/ getCalledKtaPaths() {
|
|
132
|
+
const ktaPaths = [];
|
|
133
|
+
for (const ktaKey of this.coordinateCalls.keys()){
|
|
134
|
+
ktaPaths.push(ktaKey.split('.'));
|
|
135
|
+
}
|
|
136
|
+
return ktaPaths;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Creates a normalized scope key from scopes array
|
|
140
|
+
*/ createScopeKey(scopes) {
|
|
141
|
+
if (scopes.length === 0) return '__no_scopes__';
|
|
142
|
+
return [
|
|
143
|
+
...scopes
|
|
144
|
+
].sort().join(',');
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Parses a scope key back to scopes array
|
|
148
|
+
*/ parseScopeKey(scopeKey) {
|
|
149
|
+
if (scopeKey === '__no_scopes__') return [];
|
|
150
|
+
return scopeKey.split(',');
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Creates a normalized client key from client identifier
|
|
154
|
+
*/ createClientKey(client) {
|
|
155
|
+
if (!client) return '__no_client__';
|
|
156
|
+
if (typeof client === 'string') {
|
|
157
|
+
return `app:${client}`;
|
|
158
|
+
}
|
|
159
|
+
// Service client
|
|
160
|
+
const coordKey = `${client.coordinate.kta.join('.')};${this.createScopeKey(client.coordinate.scopes)}`;
|
|
161
|
+
return `service:${client.registryType}:${coordKey}`;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Parses a client key back to client identifier
|
|
165
|
+
*/ parseClientKey(clientKey) {
|
|
166
|
+
if (clientKey === '__no_client__') return null;
|
|
167
|
+
if (clientKey.startsWith('app:')) {
|
|
168
|
+
return clientKey.substring(4);
|
|
169
|
+
}
|
|
170
|
+
if (clientKey.startsWith('service:')) {
|
|
171
|
+
const parts = clientKey.substring(8).split(':');
|
|
172
|
+
if (parts.length !== 2) return null;
|
|
173
|
+
const registryType = parts[0];
|
|
174
|
+
const coordParts = parts[1].split(';');
|
|
175
|
+
if (coordParts.length !== 2) return null;
|
|
176
|
+
const kta = coordParts[0].split('.');
|
|
177
|
+
const scopes = this.parseScopeKey(coordParts[1]);
|
|
178
|
+
return {
|
|
179
|
+
registryType,
|
|
180
|
+
coordinate: {
|
|
181
|
+
kta,
|
|
182
|
+
scopes
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
constructor(){
|
|
189
|
+
_define_property(this, "totalCalls", 0);
|
|
190
|
+
// Map structure: ktaKey -> scopeKey -> clientKey -> count
|
|
191
|
+
_define_property(this, "coordinateCalls", new Map());
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export { RegistryStats };
|
|
196
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVnaXN0cnlTdGF0cy5qcyIsInNvdXJjZXMiOltdLCJzb3VyY2VzQ29udGVudCI6W10sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7In0=
|