@routr/location 2.0.5-alpha.2 → 2.0.5-alpha.21
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/client.d.ts +47 -0
- package/dist/client.js +102 -0
- package/dist/config/get_config.d.ts +1 -1
- package/dist/config/get_config.js +38 -35
- package/dist/config/schema.d.ts +13 -10
- package/dist/config/schema.js +48 -45
- package/dist/errors.d.ts +37 -1
- package/dist/errors.js +88 -59
- package/dist/helper.d.ts +2 -0
- package/dist/helper.js +28 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +55 -0
- package/dist/location.d.ts +26 -0
- package/dist/location.js +118 -0
- package/dist/memory_store.d.ts +15 -1
- package/dist/memory_store.js +37 -48
- package/dist/redis_store.d.ts +21 -0
- package/dist/redis_store.js +99 -0
- package/dist/runner.js +12 -7
- package/dist/service.d.ts +5 -0
- package/dist/service.js +44 -6
- package/dist/tracer.d.ts +7 -0
- package/dist/tracer.js +53 -0
- package/dist/types.d.ts +19 -17
- package/dist/types.js +6 -19
- package/dist/utils.d.ts +4 -4
- package/dist/utils.js +78 -98
- package/package.json +18 -6
- package/dist/locator.d.ts +0 -13
- package/dist/locator.js +0 -152
package/dist/types.d.ts
CHANGED
|
@@ -1,28 +1,22 @@
|
|
|
1
|
+
import { Route } from "@routr/common";
|
|
1
2
|
export declare enum LB_ALGORITHM {
|
|
2
3
|
ROUND_ROBIN = "round-robin",
|
|
3
4
|
LEAST_SESSIONS = "least-sessions"
|
|
4
5
|
}
|
|
6
|
+
export declare enum CACHE_PROVIDER {
|
|
7
|
+
MEMORY = "memory",
|
|
8
|
+
REDIS = "redis"
|
|
9
|
+
}
|
|
5
10
|
export interface ILocationService {
|
|
6
11
|
addRoute(request: AddRouteRequest): Promise<void>;
|
|
7
12
|
findRoutes(request: FindRoutesRequest): Promise<Route[]>;
|
|
8
|
-
removeRoutes(request:
|
|
13
|
+
removeRoutes(request: RemoveRoutesRequest): Promise<void>;
|
|
9
14
|
}
|
|
10
15
|
export interface ILocatorStore {
|
|
11
16
|
put(key: string, route: Route): Promise<void>;
|
|
12
17
|
get(key: string): Promise<Route[]>;
|
|
13
18
|
delete(key: string): Promise<void>;
|
|
14
19
|
}
|
|
15
|
-
export interface Route {
|
|
16
|
-
user: string;
|
|
17
|
-
host: string;
|
|
18
|
-
port: number;
|
|
19
|
-
transport: string;
|
|
20
|
-
registeredOn: number;
|
|
21
|
-
sessionCount?: number;
|
|
22
|
-
expires: number;
|
|
23
|
-
edgePortRef: string;
|
|
24
|
-
labels?: Map<string, string>;
|
|
25
|
-
}
|
|
26
20
|
export interface AddRouteRequest {
|
|
27
21
|
aor: string;
|
|
28
22
|
route: Route;
|
|
@@ -35,18 +29,26 @@ export interface FindRoutesRequest {
|
|
|
35
29
|
export interface FindRoutesResponse {
|
|
36
30
|
routes: Array<Route>;
|
|
37
31
|
}
|
|
38
|
-
export interface
|
|
32
|
+
export interface RemoveRoutesRequest {
|
|
39
33
|
aor: string;
|
|
40
34
|
}
|
|
41
35
|
export interface Backend {
|
|
42
36
|
ref: string;
|
|
43
37
|
balancingAlgorithm?: LB_ALGORITHM;
|
|
44
|
-
|
|
45
|
-
enabled: boolean;
|
|
46
|
-
ref: string;
|
|
47
|
-
};
|
|
38
|
+
withSessionAffinity?: boolean;
|
|
48
39
|
}
|
|
49
40
|
export interface LocationConfig {
|
|
50
41
|
bindAddr: string;
|
|
51
42
|
backends?: Backend[];
|
|
43
|
+
cache?: {
|
|
44
|
+
provider: CACHE_PROVIDER;
|
|
45
|
+
parameters?: string;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export interface RedisStoreConfig {
|
|
49
|
+
username?: string;
|
|
50
|
+
password?: string;
|
|
51
|
+
host: string;
|
|
52
|
+
port: number;
|
|
53
|
+
secure?: boolean;
|
|
52
54
|
}
|
package/dist/types.js
CHANGED
|
@@ -1,26 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LB_ALGORITHM = void 0;
|
|
4
|
-
/*
|
|
5
|
-
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
|
6
|
-
* http://github.com/fonoster/routr
|
|
7
|
-
*
|
|
8
|
-
* This file is part of Routr
|
|
9
|
-
*
|
|
10
|
-
* Licensed under the MIT License (the "License")
|
|
11
|
-
* you may not use this file except in compliance with
|
|
12
|
-
* the License. You may obtain a copy of the License at
|
|
13
|
-
*
|
|
14
|
-
* https://opensource.org/licenses/MIT
|
|
15
|
-
*
|
|
16
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
-
* See the License for the specific language governing permissions and
|
|
20
|
-
* limitations under the License.
|
|
21
|
-
*/
|
|
3
|
+
exports.CACHE_PROVIDER = exports.LB_ALGORITHM = void 0;
|
|
22
4
|
var LB_ALGORITHM;
|
|
23
5
|
(function (LB_ALGORITHM) {
|
|
24
6
|
LB_ALGORITHM["ROUND_ROBIN"] = "round-robin";
|
|
25
7
|
LB_ALGORITHM["LEAST_SESSIONS"] = "least-sessions";
|
|
26
8
|
})(LB_ALGORITHM = exports.LB_ALGORITHM || (exports.LB_ALGORITHM = {}));
|
|
9
|
+
var CACHE_PROVIDER;
|
|
10
|
+
(function (CACHE_PROVIDER) {
|
|
11
|
+
CACHE_PROVIDER["MEMORY"] = "memory";
|
|
12
|
+
CACHE_PROVIDER["REDIS"] = "redis";
|
|
13
|
+
})(CACHE_PROVIDER = exports.CACHE_PROVIDER || (exports.CACHE_PROVIDER = {}));
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Route, ServiceInfo } from "@routr/common";
|
|
2
|
+
import { ILocationService } from "./types";
|
|
3
3
|
export declare const expiredFilter: (r: Route) => boolean;
|
|
4
4
|
export declare const duplicateFilter: (r1: Route, r2: Route) => boolean;
|
|
5
5
|
export declare const mergeKeyValue: (map: Map<string, string>) => string[];
|
|
6
6
|
export declare const compareArrays: (arr: string[], target: string[]) => boolean;
|
|
7
7
|
export declare const filterOnlyMatchingLabels: (requestLabels: Map<string, string>) => (route: Route) => boolean;
|
|
8
|
-
export declare const
|
|
9
|
-
export declare
|
|
8
|
+
export declare const getServiceInfo: (bindAddr: string, locator: ILocationService) => ServiceInfo;
|
|
9
|
+
export declare const configFromString: (params: string, allowedKeys: string[]) => Record<string, string | boolean>;
|
package/dist/utils.js
CHANGED
|
@@ -8,67 +8,48 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
12
|
+
exports.configFromString = exports.getServiceInfo = exports.filterOnlyMatchingLabels = exports.compareArrays = exports.mergeKeyValue = exports.duplicateFilter = exports.expiredFilter = void 0;
|
|
13
|
+
/*
|
|
14
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
|
15
|
+
* http://github.com/fonoster/routr
|
|
16
|
+
*
|
|
17
|
+
* This file is part of Routr
|
|
18
|
+
*
|
|
19
|
+
* Licensed under the MIT License (the "License")
|
|
20
|
+
* you may not use this file except in compliance with
|
|
21
|
+
* the License. You may obtain a copy of the License at
|
|
22
|
+
*
|
|
23
|
+
* https://opensource.org/licenses/MIT
|
|
24
|
+
*
|
|
25
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
26
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
27
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
28
|
+
* See the License for the specific language governing permissions and
|
|
29
|
+
* limitations under the License.
|
|
30
|
+
*/
|
|
31
|
+
const common_1 = require("@routr/common");
|
|
32
|
+
const errors_1 = require("./errors");
|
|
33
|
+
const expiredFilter = (r) => r.expires - (Date.now() - r.registeredOn) / 1000 > 0;
|
|
45
34
|
exports.expiredFilter = expiredFilter;
|
|
46
|
-
|
|
47
|
-
return !(r1.host === r2.host && r1.port === r2.port);
|
|
48
|
-
};
|
|
35
|
+
const duplicateFilter = (r1, r2) => !(r1.host === r2.host && r1.port === r2.port);
|
|
49
36
|
exports.duplicateFilter = duplicateFilter;
|
|
50
|
-
|
|
37
|
+
const mergeKeyValue = (map) => Array.from(map).map((l) => l[0] + l[1]);
|
|
51
38
|
exports.mergeKeyValue = mergeKeyValue;
|
|
52
|
-
|
|
53
|
-
return target.every(function (v) { return arr.includes(v); }) && arr.length === target.length;
|
|
54
|
-
};
|
|
39
|
+
const compareArrays = (arr, target) => target.every((v) => arr.includes(v)) && arr.length === target.length;
|
|
55
40
|
exports.compareArrays = compareArrays;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
: false; };
|
|
60
|
-
};
|
|
41
|
+
const filterOnlyMatchingLabels = (requestLabels) => (route) => route.labels
|
|
42
|
+
? (0, exports.compareArrays)((0, exports.mergeKeyValue)(requestLabels), (0, exports.mergeKeyValue)(route.labels))
|
|
43
|
+
: false;
|
|
61
44
|
exports.filterOnlyMatchingLabels = filterOnlyMatchingLabels;
|
|
62
|
-
|
|
63
|
-
exports.hasAffinitySession = hasAffinitySession;
|
|
64
|
-
function getServiceInfo(bindAddr, locator) {
|
|
65
|
-
var _this = this;
|
|
45
|
+
const getServiceInfo = (bindAddr, locator) => {
|
|
66
46
|
return {
|
|
67
47
|
name: "location",
|
|
68
|
-
bindAddr
|
|
48
|
+
bindAddr,
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
50
|
service: common_1.LOCATION_OBJECT_PROTO.Location.service,
|
|
70
51
|
handlers: {
|
|
71
|
-
addRoute:
|
|
52
|
+
addRoute: (call, callback) => {
|
|
72
53
|
try {
|
|
73
54
|
locator.addRoute(call.request);
|
|
74
55
|
callback(null, {});
|
|
@@ -77,53 +58,52 @@ function getServiceInfo(bindAddr, locator) {
|
|
|
77
58
|
callback(e, null);
|
|
78
59
|
}
|
|
79
60
|
},
|
|
80
|
-
findRoutes:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
removeRoutes: function (call, callback) { return __awaiter(_this, void 0, void 0, function () {
|
|
104
|
-
var _a, _b, e_2;
|
|
105
|
-
var _c;
|
|
106
|
-
return __generator(this, function (_d) {
|
|
107
|
-
switch (_d.label) {
|
|
108
|
-
case 0:
|
|
109
|
-
_d.trys.push([0, 2, , 3]);
|
|
110
|
-
_a = callback;
|
|
111
|
-
_b = [null];
|
|
112
|
-
_c = {};
|
|
113
|
-
return [4 /*yield*/, locator.findRoutes(call.request)];
|
|
114
|
-
case 1:
|
|
115
|
-
_a.apply(void 0, _b.concat([(_c.routes = _d.sent(),
|
|
116
|
-
_c)]));
|
|
117
|
-
return [3 /*break*/, 3];
|
|
118
|
-
case 2:
|
|
119
|
-
e_2 = _d.sent();
|
|
120
|
-
callback(e_2, null);
|
|
121
|
-
return [3 /*break*/, 3];
|
|
122
|
-
case 3: return [2 /*return*/];
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
}); }
|
|
61
|
+
findRoutes: (call, callback) => __awaiter(void 0, void 0, void 0, function* () {
|
|
62
|
+
try {
|
|
63
|
+
const routes = yield locator.findRoutes(call.request);
|
|
64
|
+
if (routes.length === 0)
|
|
65
|
+
throw new errors_1.NotRoutesFoundForAOR(call.request.aor);
|
|
66
|
+
callback(null, {
|
|
67
|
+
routes: routes
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
callback(e, null);
|
|
72
|
+
}
|
|
73
|
+
}),
|
|
74
|
+
removeRoutes: (call, callback) => __awaiter(void 0, void 0, void 0, function* () {
|
|
75
|
+
try {
|
|
76
|
+
callback(null, {
|
|
77
|
+
routes: yield locator.findRoutes(call.request)
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
callback(e, null);
|
|
82
|
+
}
|
|
83
|
+
})
|
|
126
84
|
}
|
|
127
85
|
};
|
|
128
|
-
}
|
|
86
|
+
};
|
|
129
87
|
exports.getServiceInfo = getServiceInfo;
|
|
88
|
+
const configFromString = (params, allowedKeys) => {
|
|
89
|
+
if (params.length === 0)
|
|
90
|
+
return {};
|
|
91
|
+
const parameters = {};
|
|
92
|
+
params.split(",").forEach((par) => {
|
|
93
|
+
try {
|
|
94
|
+
const key = par.split("=")[0];
|
|
95
|
+
const value = par.split("=")[1];
|
|
96
|
+
if (allowedKeys.indexOf(key) === -1) {
|
|
97
|
+
throw new Error(`invalid parameter: ${key}`);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
parameters[key] = value === "true" ? true : value;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
throw new Error(`invalid parameters string: ${params}; should be something like 'host=localhost,port=6379'`);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return parameters;
|
|
108
|
+
};
|
|
109
|
+
exports.configFromString = configFromString;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@routr/location",
|
|
3
|
-
"version": "2.0.5-alpha.
|
|
3
|
+
"version": "2.0.5-alpha.21",
|
|
4
4
|
"description": "Creates and maintains a list of routes to all registered endpoints",
|
|
5
5
|
"author": "Pedro Sanders <psanders@fonoster.com>",
|
|
6
6
|
"homepage": "https://github.com/fonoster/routr#readme",
|
|
7
7
|
"license": "MIT",
|
|
8
|
-
"main": "dist/
|
|
9
|
-
"types": "dist/
|
|
8
|
+
"main": "dist/index",
|
|
9
|
+
"types": "dist/index",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"prebuild": "rimraf ./dist tsconfig.tsbuildinfo",
|
|
12
12
|
"build": "tsc -b tsconfig.json"
|
|
@@ -25,9 +25,21 @@
|
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@
|
|
28
|
+
"@fonoster/logger": "0.3.17-alpha.2",
|
|
29
|
+
"@grpc/grpc-js": "^1.5.9",
|
|
30
|
+
"@opentelemetry/api": "^1.0.4",
|
|
31
|
+
"@opentelemetry/exporter-jaeger": "^1.0.4",
|
|
32
|
+
"@opentelemetry/instrumentation": "^0.27.0",
|
|
33
|
+
"@opentelemetry/instrumentation-grpc": "^0.27.0",
|
|
34
|
+
"@opentelemetry/resources": "^1.0.4",
|
|
35
|
+
"@opentelemetry/sdk-trace-base": "^1.0.4",
|
|
36
|
+
"@opentelemetry/sdk-trace-node": "^1.0.4",
|
|
37
|
+
"@opentelemetry/semantic-conventions": "^1.0.4",
|
|
38
|
+
"@routr/common": "^2.0.5-alpha.21",
|
|
39
|
+
"@routr/processor": "^2.0.5-alpha.21",
|
|
29
40
|
"ajv": "^6.12.6",
|
|
30
|
-
"fp-ts": "^2.11.8"
|
|
41
|
+
"fp-ts": "^2.11.8",
|
|
42
|
+
"redis": "^4.0.4"
|
|
31
43
|
},
|
|
32
44
|
"repository": {
|
|
33
45
|
"type": "git",
|
|
@@ -36,5 +48,5 @@
|
|
|
36
48
|
"bugs": {
|
|
37
49
|
"url": "https://github.com/fonoster/routr/issues"
|
|
38
50
|
},
|
|
39
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "904559d8d4694e16d63f553704345a987dc0d93a"
|
|
40
52
|
}
|
package/dist/locator.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { AddRouteRequest, Backend, FindRoutesRequest, ILocationService, ILocatorStore, RemoveRouteRequest, Route } from "./types";
|
|
2
|
-
export default class Locator implements ILocationService {
|
|
3
|
-
private store;
|
|
4
|
-
private backends;
|
|
5
|
-
private rrCount;
|
|
6
|
-
private affinityStore;
|
|
7
|
-
constructor(store: ILocatorStore, backends?: Map<string, Backend>);
|
|
8
|
-
addRoute(request: AddRouteRequest): Promise<void>;
|
|
9
|
-
findRoutes(request: FindRoutesRequest): Promise<Route[]>;
|
|
10
|
-
removeRoutes(request: RemoveRouteRequest): Promise<void>;
|
|
11
|
-
private next;
|
|
12
|
-
private nextWithAffinity;
|
|
13
|
-
}
|
package/dist/locator.js
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
/*
|
|
40
|
-
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
|
41
|
-
* http://github.com/fonoster/routr
|
|
42
|
-
*
|
|
43
|
-
* This file is part of Routr
|
|
44
|
-
*
|
|
45
|
-
* Licensed under the MIT License (the "License")
|
|
46
|
-
* you may not use this file except in compliance with
|
|
47
|
-
* the License. You may obtain a copy of the License at
|
|
48
|
-
*
|
|
49
|
-
* https://opensource.org/licenses/MIT
|
|
50
|
-
*
|
|
51
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
52
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
53
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
54
|
-
* See the License for the specific language governing permissions and
|
|
55
|
-
* limitations under the License.
|
|
56
|
-
*/
|
|
57
|
-
var errors_1 = require("./errors");
|
|
58
|
-
var types_1 = require("./types");
|
|
59
|
-
var utils_1 = require("./utils");
|
|
60
|
-
var Locator = /** @class */ (function () {
|
|
61
|
-
// Should fail if any backend has sessionAffinity and round-robin
|
|
62
|
-
function Locator(store, backends) {
|
|
63
|
-
var _this = this;
|
|
64
|
-
if (backends === void 0) { backends = new Map(); }
|
|
65
|
-
this.store = store;
|
|
66
|
-
this.backends = backends;
|
|
67
|
-
this.rrCount = new Map();
|
|
68
|
-
this.affinityStore = new Map();
|
|
69
|
-
this.backends.forEach(function (value, key) { return _this.rrCount.set(key, 0); });
|
|
70
|
-
}
|
|
71
|
-
Locator.prototype.addRoute = function (request) {
|
|
72
|
-
if (!request.aor.startsWith('sip:') &&
|
|
73
|
-
!request.aor.startsWith('backend:')) {
|
|
74
|
-
throw new errors_1.UnsupportedSchema(request.aor);
|
|
75
|
-
}
|
|
76
|
-
return this.store.put(request.aor, request.route);
|
|
77
|
-
};
|
|
78
|
-
Locator.prototype.findRoutes = function (request) {
|
|
79
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
80
|
-
var routes, _a, backend, _b, _c;
|
|
81
|
-
return __generator(this, function (_d) {
|
|
82
|
-
switch (_d.label) {
|
|
83
|
-
case 0:
|
|
84
|
-
if (!request.labels) return [3 /*break*/, 2];
|
|
85
|
-
return [4 /*yield*/, this.store.get(request.aor)];
|
|
86
|
-
case 1:
|
|
87
|
-
_a = (_d.sent())
|
|
88
|
-
.filter(utils_1.filterOnlyMatchingLabels(request.labels));
|
|
89
|
-
return [3 /*break*/, 4];
|
|
90
|
-
case 2: return [4 /*yield*/, this.store.get(request.aor)];
|
|
91
|
-
case 3:
|
|
92
|
-
_a = (_d.sent()) || [];
|
|
93
|
-
_d.label = 4;
|
|
94
|
-
case 4:
|
|
95
|
-
routes = _a;
|
|
96
|
-
if (!request.aor.startsWith('sip:')) return [3 /*break*/, 5];
|
|
97
|
-
return [2 /*return*/, routes];
|
|
98
|
-
case 5:
|
|
99
|
-
if (!request.aor.startsWith('backend:')) return [3 /*break*/, 9];
|
|
100
|
-
backend = this.backends.get(request.aor);
|
|
101
|
-
if (!backend) {
|
|
102
|
-
throw new errors_1.NotRoutesFoundForAOR(request.aor);
|
|
103
|
-
}
|
|
104
|
-
if (!!utils_1.hasAffinitySession(backend)) return [3 /*break*/, 6];
|
|
105
|
-
_b = [this.next(routes, backend)];
|
|
106
|
-
return [3 /*break*/, 8];
|
|
107
|
-
case 6:
|
|
108
|
-
_c = this.nextWithAffinity;
|
|
109
|
-
return [4 /*yield*/, routes];
|
|
110
|
-
case 7:
|
|
111
|
-
_b = [_c.apply(this, [_d.sent(), backend.sessionAffinity.ref])];
|
|
112
|
-
_d.label = 8;
|
|
113
|
-
case 8:
|
|
114
|
-
// If it has not affinity sesssion then get next
|
|
115
|
-
return [2 /*return*/, _b];
|
|
116
|
-
case 9: throw new errors_1.UnsupportedSchema(request.aor);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
};
|
|
121
|
-
Locator.prototype.removeRoutes = function (request) {
|
|
122
|
-
return this.store.delete(request.aor);
|
|
123
|
-
};
|
|
124
|
-
Locator.prototype.next = function (routes, backend) {
|
|
125
|
-
if (backend.balancingAlgorithm === types_1.LB_ALGORITHM.LEAST_SESSIONS) {
|
|
126
|
-
return routes.sort(function (r1, r2) { return r1.sessionCount - r2.sessionCount; })[0];
|
|
127
|
-
}
|
|
128
|
-
// Continues using round-robin
|
|
129
|
-
var nextPosition = this.rrCount.get("backend:" + backend.ref);
|
|
130
|
-
var result = routes[nextPosition];
|
|
131
|
-
if (nextPosition >= (routes.length - 1)) {
|
|
132
|
-
// Restarting round-robin counter
|
|
133
|
-
this.rrCount.set("backend:" + backend.ref, 0);
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
this.rrCount.set("backend:" + backend.ref, nextPosition + 1);
|
|
137
|
-
}
|
|
138
|
-
return result;
|
|
139
|
-
};
|
|
140
|
-
// Backend with session affinity does not support round-robin
|
|
141
|
-
Locator.prototype.nextWithAffinity = function (routes, sessionAffinityRef) {
|
|
142
|
-
var route = this.affinityStore.get(sessionAffinityRef);
|
|
143
|
-
if (route) {
|
|
144
|
-
return route;
|
|
145
|
-
}
|
|
146
|
-
route = routes.sort(function (r1, r2) { return r1.sessionCount - r2.sessionCount; })[0];
|
|
147
|
-
this.affinityStore.set(sessionAffinityRef, route);
|
|
148
|
-
return route;
|
|
149
|
-
};
|
|
150
|
-
return Locator;
|
|
151
|
-
}());
|
|
152
|
-
exports.default = Locator;
|