@fluyappgocore/commons-backend 1.0.202
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/build/classes/BacklogManager.d.ts +129 -0
- package/build/classes/BacklogManager.js +417 -0
- package/build/classes/BacklogMonitor.d.ts +102 -0
- package/build/classes/BacklogMonitor.js +222 -0
- package/build/classes/HttpResponse.d.ts +7 -0
- package/build/classes/HttpResponse.js +13 -0
- package/build/classes/index.d.ts +3 -0
- package/build/classes/index.js +15 -0
- package/build/dtos/file.dto.d.ts +5 -0
- package/build/dtos/file.dto.js +25 -0
- package/build/dtos/index.d.ts +1 -0
- package/build/dtos/index.js +13 -0
- package/build/events/BatchEnhancedListener.d.ts +106 -0
- package/build/events/BatchEnhancedListener.js +307 -0
- package/build/events/EnhancedListener.d.ts +75 -0
- package/build/events/EnhancedListener.js +185 -0
- package/build/events/baseListener.d.ts +19 -0
- package/build/events/baseListener.js +90 -0
- package/build/events/basePublisher.d.ts +14 -0
- package/build/events/basePublisher.js +84 -0
- package/build/events/config.d.ts +7 -0
- package/build/events/config.js +14 -0
- package/build/events/createClient.d.ts +38 -0
- package/build/events/createClient.js +416 -0
- package/build/events/index.d.ts +6 -0
- package/build/events/index.js +18 -0
- package/build/events/interfaces/agent.event.d.ts +7 -0
- package/build/events/interfaces/agent.event.js +2 -0
- package/build/events/interfaces/agentCrud.event.d.ts +7 -0
- package/build/events/interfaces/agentCrud.event.js +2 -0
- package/build/events/interfaces/agentTracking.event.d.ts +7 -0
- package/build/events/interfaces/agentTracking.event.js +2 -0
- package/build/events/interfaces/audit.event.d.ts +7 -0
- package/build/events/interfaces/audit.event.js +2 -0
- package/build/events/interfaces/branch.event.d.ts +7 -0
- package/build/events/interfaces/branch.event.js +2 -0
- package/build/events/interfaces/deleteTracking.event.d.ts +7 -0
- package/build/events/interfaces/deleteTracking.event.js +2 -0
- package/build/events/interfaces/department.event.d.ts +7 -0
- package/build/events/interfaces/department.event.js +2 -0
- package/build/events/interfaces/entity.event.d.ts +7 -0
- package/build/events/interfaces/entity.event.js +2 -0
- package/build/events/interfaces/index.d.ts +23 -0
- package/build/events/interfaces/index.js +35 -0
- package/build/events/interfaces/manualMatch.event.d.ts +7 -0
- package/build/events/interfaces/manualMatch.event.js +2 -0
- package/build/events/interfaces/match.event.d.ts +7 -0
- package/build/events/interfaces/match.event.js +2 -0
- package/build/events/interfaces/monitor.event.d.ts +7 -0
- package/build/events/interfaces/monitor.event.js +2 -0
- package/build/events/interfaces/notification.event.d.ts +7 -0
- package/build/events/interfaces/notification.event.js +2 -0
- package/build/events/interfaces/object.event.d.ts +7 -0
- package/build/events/interfaces/object.event.js +2 -0
- package/build/events/interfaces/payments.event.d.ts +7 -0
- package/build/events/interfaces/payments.event.js +2 -0
- package/build/events/interfaces/planning.event.d.ts +7 -0
- package/build/events/interfaces/planning.event.js +2 -0
- package/build/events/interfaces/service.event.d.ts +7 -0
- package/build/events/interfaces/service.event.js +2 -0
- package/build/events/interfaces/subscription.event.d.ts +7 -0
- package/build/events/interfaces/subscription.event.js +2 -0
- package/build/events/interfaces/ticket.event.d.ts +7 -0
- package/build/events/interfaces/ticket.event.js +2 -0
- package/build/events/interfaces/ticketNote.event.d.ts +7 -0
- package/build/events/interfaces/ticketNote.event.js +2 -0
- package/build/events/interfaces/ticketTracking.event.d.ts +7 -0
- package/build/events/interfaces/ticketTracking.event.js +2 -0
- package/build/events/interfaces/ticketxTopics.event.d.ts +7 -0
- package/build/events/interfaces/ticketxTopics.event.js +2 -0
- package/build/events/interfaces/topics.event.d.ts +7 -0
- package/build/events/interfaces/topics.event.js +2 -0
- package/build/events/interfaces/waitingList.event.d.ts +7 -0
- package/build/events/interfaces/waitingList.event.js +2 -0
- package/build/exceptions/AuthenticationTokenMissingException.d.ts +5 -0
- package/build/exceptions/AuthenticationTokenMissingException.js +27 -0
- package/build/exceptions/HttpException.d.ts +5 -0
- package/build/exceptions/HttpException.js +27 -0
- package/build/exceptions/MongoErrorException.d.ts +4 -0
- package/build/exceptions/MongoErrorException.js +27 -0
- package/build/exceptions/MulterException.d.ts +4 -0
- package/build/exceptions/MulterException.js +27 -0
- package/build/exceptions/QwizardException.d.ts +5 -0
- package/build/exceptions/QwizardException.js +27 -0
- package/build/exceptions/RecordingServerException.d.ts +5 -0
- package/build/exceptions/RecordingServerException.js +27 -0
- package/build/exceptions/UserNotFoundException.d.ts +4 -0
- package/build/exceptions/UserNotFoundException.js +27 -0
- package/build/exceptions/UserWithThatEmailAlreadyExistsException.d.ts +4 -0
- package/build/exceptions/UserWithThatEmailAlreadyExistsException.js +27 -0
- package/build/exceptions/WrongAnonymousAuthException.d.ts +5 -0
- package/build/exceptions/WrongAnonymousAuthException.js +27 -0
- package/build/exceptions/WrongAuthenticationTokenException.d.ts +5 -0
- package/build/exceptions/WrongAuthenticationTokenException.js +27 -0
- package/build/exceptions/WrongBusinessAuthException.d.ts +5 -0
- package/build/exceptions/WrongBusinessAuthException.js +27 -0
- package/build/exceptions/WrongCredentialsException.d.ts +4 -0
- package/build/exceptions/WrongCredentialsException.js +27 -0
- package/build/exceptions/WrongRoomException.d.ts +4 -0
- package/build/exceptions/WrongRoomException.js +27 -0
- package/build/exceptions/index.d.ts +16 -0
- package/build/exceptions/index.js +28 -0
- package/build/exceptions/invalidToken.exception.d.ts +4 -0
- package/build/exceptions/invalidToken.exception.js +27 -0
- package/build/exceptions/missingToken.exception.d.ts +4 -0
- package/build/exceptions/missingToken.exception.js +27 -0
- package/build/exceptions/wrongAuth.exception.d.ts +5 -0
- package/build/exceptions/wrongAuth.exception.js +27 -0
- package/build/index.d.ts +12 -0
- package/build/index.js +32 -0
- package/build/interfaces/controller.interface.d.ts +5 -0
- package/build/interfaces/controller.interface.js +2 -0
- package/build/interfaces/index.d.ts +3 -0
- package/build/interfaces/index.js +15 -0
- package/build/interfaces/requesWithUser.interface.d.ts +11 -0
- package/build/interfaces/requesWithUser.interface.js +2 -0
- package/build/interfaces/token.interface.d.ts +12 -0
- package/build/interfaces/token.interface.js +2 -0
- package/build/lib/ensureDatabase.d.ts +11 -0
- package/build/lib/ensureDatabase.js +97 -0
- package/build/lib/functions.d.ts +89 -0
- package/build/lib/functions.js +214 -0
- package/build/lib/helpers.d.ts +29 -0
- package/build/lib/helpers.js +33 -0
- package/build/lib/index.d.ts +4 -0
- package/build/lib/index.js +16 -0
- package/build/lib/logger.d.ts +2 -0
- package/build/lib/logger.js +41 -0
- package/build/middlewares/auth.middleware.d.ts +6 -0
- package/build/middlewares/auth.middleware.js +287 -0
- package/build/middlewares/error.middleware.d.ts +3 -0
- package/build/middlewares/error.middleware.js +14 -0
- package/build/middlewares/index.d.ts +3 -0
- package/build/middlewares/index.js +15 -0
- package/build/middlewares/validation.middleware.d.ts +2 -0
- package/build/middlewares/validation.middleware.js +22 -0
- package/package.json +45 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
+
function step(op) {
|
|
27
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
+
while (_) try {
|
|
29
|
+
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;
|
|
30
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
+
switch (op[0]) {
|
|
32
|
+
case 0: case 1: t = op; break;
|
|
33
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
+
default:
|
|
37
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
+
if (t[2]) _.ops.pop();
|
|
42
|
+
_.trys.pop(); continue;
|
|
43
|
+
}
|
|
44
|
+
op = body.call(thisArg, _);
|
|
45
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.BatchEnhancedListener = void 0;
|
|
51
|
+
var BacklogManager_1 = require("../classes/BacklogManager");
|
|
52
|
+
/**
|
|
53
|
+
* 🔥 BULLETPROOF: BatchEnhancedListener con control de flujo real en la entrada
|
|
54
|
+
*
|
|
55
|
+
* DIFERENCIAS CLAVE vs EnhancedListener:
|
|
56
|
+
* ✅ Control de flujo en la ENTRADA del consumer (eachBatch)
|
|
57
|
+
* ✅ NUNCA más mensajes en memoria de los que puede procesar
|
|
58
|
+
* ✅ Pausa automática cuando BacklogManager está saturado
|
|
59
|
+
* ✅ Resolución manual de offsets para mejor control de errores
|
|
60
|
+
* ✅ Heartbeat automático para mantener conexión viva
|
|
61
|
+
*/
|
|
62
|
+
var BatchEnhancedListener = /** @class */ (function () {
|
|
63
|
+
function BatchEnhancedListener(client, listenerName, backlogConfig, batchConfig) {
|
|
64
|
+
this.client = client;
|
|
65
|
+
this.listenerName = listenerName;
|
|
66
|
+
// Configuración específica por tipo de listener
|
|
67
|
+
var defaultConfig = this.getDefaultBacklogConfig();
|
|
68
|
+
this.backlogManager = new BacklogManager_1.BacklogManager(__assign(__assign(__assign({}, defaultConfig), backlogConfig), { listenerName: listenerName }));
|
|
69
|
+
// Guardar configuración de batch para usar en listen()
|
|
70
|
+
this.batchConfig = __assign({ maxBytesPerPartition: 10240, maxBytes: 102400 }, batchConfig);
|
|
71
|
+
console.log("\uD83D\uDE80 Batch Enhanced listener " + listenerName + " initialized with flow control");
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Configuración por defecto que puede ser sobrescrita por cada listener
|
|
75
|
+
*/
|
|
76
|
+
BatchEnhancedListener.prototype.getDefaultBacklogConfig = function () {
|
|
77
|
+
return {
|
|
78
|
+
maxConcurrent: 3,
|
|
79
|
+
rateLimitMs: 200,
|
|
80
|
+
circuitBreakerThreshold: 5,
|
|
81
|
+
circuitBreakerResetTime: 30000,
|
|
82
|
+
maxRetries: 2,
|
|
83
|
+
backlogRecoveryBatchSize: 25,
|
|
84
|
+
enableBacklogRecovery: true,
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* 🔥 BULLETPROOF: Listen usando eachBatch con control de flujo real
|
|
89
|
+
*/
|
|
90
|
+
BatchEnhancedListener.prototype.listen = function (fromBeginning) {
|
|
91
|
+
var _this = this;
|
|
92
|
+
console.log("\uD83C\uDFA7 Starting batch enhanced listener: " + this.listenerName);
|
|
93
|
+
var topic = this.topic;
|
|
94
|
+
var consumer = this.client.consumer({
|
|
95
|
+
groupId: this.groupName,
|
|
96
|
+
// Configuraciones adicionales para mejor control
|
|
97
|
+
sessionTimeout: 30000,
|
|
98
|
+
heartbeatInterval: 3000,
|
|
99
|
+
maxWaitTimeInMs: 5000,
|
|
100
|
+
// Limitar el fetch para no saturar memoria - CONFIGURACIÓN ULTRA CONSERVADORA
|
|
101
|
+
maxBytesPerPartition: this.batchConfig.maxBytesPerPartition || 10240,
|
|
102
|
+
maxBytes: this.batchConfig.maxBytes || 102400,
|
|
103
|
+
});
|
|
104
|
+
consumer
|
|
105
|
+
.connect()
|
|
106
|
+
.then(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
107
|
+
var _this = this;
|
|
108
|
+
return __generator(this, function (_a) {
|
|
109
|
+
switch (_a.label) {
|
|
110
|
+
case 0: return [4 /*yield*/, consumer.subscribe({ topic: topic, fromBeginning: fromBeginning })];
|
|
111
|
+
case 1:
|
|
112
|
+
_a.sent();
|
|
113
|
+
return [4 /*yield*/, consumer.run({
|
|
114
|
+
// 🔥 CLAVE: eachBatchAutoResolve = false para control manual
|
|
115
|
+
eachBatchAutoResolve: false,
|
|
116
|
+
eachBatch: function (payload) { return __awaiter(_this, void 0, void 0, function () {
|
|
117
|
+
return __generator(this, function (_a) {
|
|
118
|
+
switch (_a.label) {
|
|
119
|
+
case 0: return [4 /*yield*/, this.processBatch(payload)];
|
|
120
|
+
case 1:
|
|
121
|
+
_a.sent();
|
|
122
|
+
return [2 /*return*/];
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}); },
|
|
126
|
+
})];
|
|
127
|
+
case 2:
|
|
128
|
+
_a.sent();
|
|
129
|
+
return [2 /*return*/];
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}); })
|
|
133
|
+
.catch(function (error) {
|
|
134
|
+
console.error("\uD83D\uDCA5 KAFKA ERROR in " + _this.listenerName + ":", error);
|
|
135
|
+
});
|
|
136
|
+
// Iniciar monitoreo de estadísticas cada 30 segundos
|
|
137
|
+
setInterval(function () {
|
|
138
|
+
_this.logStats();
|
|
139
|
+
}, 30000);
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* 🔥 BULLETPROOF: Procesa batch con control de flujo real
|
|
143
|
+
*/
|
|
144
|
+
BatchEnhancedListener.prototype.processBatch = function (payload) {
|
|
145
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
146
|
+
var batch, resolveOffset, heartbeat, isRunning, isStale, _i, _a, message, hasCapacity, parsedData, success, error_1;
|
|
147
|
+
var _this = this;
|
|
148
|
+
return __generator(this, function (_b) {
|
|
149
|
+
switch (_b.label) {
|
|
150
|
+
case 0:
|
|
151
|
+
batch = payload.batch, resolveOffset = payload.resolveOffset, heartbeat = payload.heartbeat, isRunning = payload.isRunning, isStale = payload.isStale;
|
|
152
|
+
console.log("\uD83D\uDCE6 Processing batch: " + batch.messages.length + " messages for " + this.listenerName);
|
|
153
|
+
_i = 0, _a = batch.messages;
|
|
154
|
+
_b.label = 1;
|
|
155
|
+
case 1:
|
|
156
|
+
if (!(_i < _a.length)) return [3 /*break*/, 11];
|
|
157
|
+
message = _a[_i];
|
|
158
|
+
_b.label = 2;
|
|
159
|
+
case 2:
|
|
160
|
+
if (!this.backlogManager.isAtMaxCapacity()) return [3 /*break*/, 5];
|
|
161
|
+
console.log("\u23F8\uFE0F " + this.listenerName + " pausing batch - at max capacity");
|
|
162
|
+
return [4 /*yield*/, this.backlogManager.waitForCapacity(1, 10000)];
|
|
163
|
+
case 3:
|
|
164
|
+
hasCapacity = _b.sent();
|
|
165
|
+
if (!hasCapacity) {
|
|
166
|
+
console.error("\u274C " + this.listenerName + " timeout waiting for capacity");
|
|
167
|
+
// No resolver offset para reintentar este mensaje
|
|
168
|
+
return [2 /*return*/];
|
|
169
|
+
}
|
|
170
|
+
// Mantener conexión viva
|
|
171
|
+
return [4 /*yield*/, heartbeat()];
|
|
172
|
+
case 4:
|
|
173
|
+
// Mantener conexión viva
|
|
174
|
+
_b.sent();
|
|
175
|
+
// Verificar si el consumer sigue activo
|
|
176
|
+
if (!isRunning() || isStale()) {
|
|
177
|
+
console.warn("\u26A0\uFE0F " + this.listenerName + " consumer not running or stale");
|
|
178
|
+
return [2 /*return*/];
|
|
179
|
+
}
|
|
180
|
+
return [3 /*break*/, 2];
|
|
181
|
+
case 5:
|
|
182
|
+
_b.trys.push([5, 7, , 8]);
|
|
183
|
+
parsedData = this.parseMessage(message);
|
|
184
|
+
return [4 /*yield*/, this.backlogManager.processMessage({ data: parsedData, msg: message }, function (_a) {
|
|
185
|
+
var data = _a.data, msg = _a.msg;
|
|
186
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
187
|
+
return __generator(this, function (_b) {
|
|
188
|
+
switch (_b.label) {
|
|
189
|
+
case 0: return [4 /*yield*/, this.processMessage(data, msg)];
|
|
190
|
+
case 1:
|
|
191
|
+
_b.sent();
|
|
192
|
+
return [2 /*return*/];
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
}, this.listenerName + ":" + this.topic + ":" + message.offset)];
|
|
197
|
+
case 6:
|
|
198
|
+
success = _b.sent();
|
|
199
|
+
if (success) {
|
|
200
|
+
// ✅ Solo resolver offset si el procesamiento fue exitoso
|
|
201
|
+
resolveOffset(message.offset);
|
|
202
|
+
console.log("\u2705 " + this.listenerName + " processed message offset " + message.offset);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
// ❌ No resolver offset para reintentar luego
|
|
206
|
+
console.error("\u274C " + this.listenerName + " failed to process message offset " + message.offset);
|
|
207
|
+
return [3 /*break*/, 11]; // Salir del batch para reintentar desde este punto
|
|
208
|
+
}
|
|
209
|
+
return [3 /*break*/, 8];
|
|
210
|
+
case 7:
|
|
211
|
+
error_1 = _b.sent();
|
|
212
|
+
console.error("\uD83D\uDCA5 " + this.listenerName + " critical error processing message:", error_1);
|
|
213
|
+
// No resolver offset para reintentar
|
|
214
|
+
return [3 /*break*/, 11];
|
|
215
|
+
case 8:
|
|
216
|
+
// Mantener conexión viva
|
|
217
|
+
return [4 /*yield*/, heartbeat()];
|
|
218
|
+
case 9:
|
|
219
|
+
// Mantener conexión viva
|
|
220
|
+
_b.sent();
|
|
221
|
+
_b.label = 10;
|
|
222
|
+
case 10:
|
|
223
|
+
_i++;
|
|
224
|
+
return [3 /*break*/, 1];
|
|
225
|
+
case 11:
|
|
226
|
+
console.log("\uD83D\uDCE6 Batch completed for " + this.listenerName);
|
|
227
|
+
return [2 /*return*/];
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
};
|
|
232
|
+
/**
|
|
233
|
+
* Parse message helper
|
|
234
|
+
*/
|
|
235
|
+
BatchEnhancedListener.prototype.parseMessage = function (msg) {
|
|
236
|
+
var data = msg.value || "{}";
|
|
237
|
+
return typeof data === "string" ? JSON.parse(data) : JSON.parse(data.toString("utf8"));
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* Log de estadísticas del BacklogManager
|
|
241
|
+
*/
|
|
242
|
+
BatchEnhancedListener.prototype.logStats = function () {
|
|
243
|
+
var stats = this.backlogManager.getStats();
|
|
244
|
+
if (stats.processed > 0 || stats.failed > 0) {
|
|
245
|
+
console.log("\uD83D\uDCCA " + this.listenerName + " Batch Stats:", {
|
|
246
|
+
processed: stats.processed,
|
|
247
|
+
failed: stats.failed,
|
|
248
|
+
retries: stats.retries,
|
|
249
|
+
queueSize: stats.queueSize,
|
|
250
|
+
activeProcessing: stats.activeProcessing,
|
|
251
|
+
availableCapacity: this.backlogManager.getAvailableCapacity(),
|
|
252
|
+
circuitBreakerOpen: stats.circuitBreakerOpen,
|
|
253
|
+
avgProcessingTime: stats.averageProcessingTime.toFixed(0) + "ms",
|
|
254
|
+
successRate: ((stats.processed / (stats.processed + stats.failed)) * 100).toFixed(1) + "%",
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
/**
|
|
259
|
+
* Obtener estadísticas del listener
|
|
260
|
+
*/
|
|
261
|
+
BatchEnhancedListener.prototype.getStats = function () {
|
|
262
|
+
return __assign(__assign({ listenerName: this.listenerName, topic: this.topic, groupName: this.groupName }, this.backlogManager.getStats()), { availableCapacity: this.backlogManager.getAvailableCapacity(), isAtMaxCapacity: this.backlogManager.isAtMaxCapacity() });
|
|
263
|
+
};
|
|
264
|
+
/**
|
|
265
|
+
* Actualizar configuración del BacklogManager en tiempo real
|
|
266
|
+
*/
|
|
267
|
+
BatchEnhancedListener.prototype.updateBacklogConfig = function (newConfig) {
|
|
268
|
+
this.backlogManager.updateConfig(newConfig);
|
|
269
|
+
console.log("\uD83D\uDD27 " + this.listenerName + " batch backlog config updated");
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* Resetear estadísticas
|
|
273
|
+
*/
|
|
274
|
+
BatchEnhancedListener.prototype.resetStats = function () {
|
|
275
|
+
this.backlogManager.resetStats();
|
|
276
|
+
console.log("\uD83D\uDD04 " + this.listenerName + " batch stats reset");
|
|
277
|
+
};
|
|
278
|
+
/**
|
|
279
|
+
* Forzar circuit breaker (para debugging)
|
|
280
|
+
*/
|
|
281
|
+
BatchEnhancedListener.prototype.forceCircuitBreaker = function (open) {
|
|
282
|
+
if (open) {
|
|
283
|
+
this.backlogManager.forceCircuitBreakerOpen();
|
|
284
|
+
console.log("\uD83D\uDD34 " + this.listenerName + " batch circuit breaker forced OPEN");
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
this.backlogManager.forceCircuitBreakerClose();
|
|
288
|
+
console.log("\uD83D\uDFE2 " + this.listenerName + " batch circuit breaker forced CLOSED");
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
/**
|
|
292
|
+
* Registra un callback para cambios de estado del circuit breaker
|
|
293
|
+
* @param callback Función que se ejecuta cuando cambia el estado del circuit breaker
|
|
294
|
+
*/
|
|
295
|
+
BatchEnhancedListener.prototype.onCircuitBreakerStateChange = function (callback) {
|
|
296
|
+
this.backlogManager.onCircuitBreakerStateChange(callback);
|
|
297
|
+
console.log("\uD83D\uDD14 " + this.listenerName + " circuit breaker callback registered");
|
|
298
|
+
};
|
|
299
|
+
/**
|
|
300
|
+
* Obtiene el nombre del listener
|
|
301
|
+
*/
|
|
302
|
+
BatchEnhancedListener.prototype.getListenerName = function () {
|
|
303
|
+
return this.listenerName;
|
|
304
|
+
};
|
|
305
|
+
return BatchEnhancedListener;
|
|
306
|
+
}());
|
|
307
|
+
exports.BatchEnhancedListener = BatchEnhancedListener;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { TicketTopics, AgentTopics, EntityTreeTopics, AgentCrudTopics, MatchTopics, TicketTrackingTopics, AgentTrackingTopics, ManualMatchTopics, MonitorTopics, UserTopics, DeleteTrackingTopics, AuditTopics, NotificationTopics, TicketNoteTopics, TopicsTopics, TicketxTopicsTopics, DeviceTopics, PlanningTopics, WaitingTopics, PaymentsTopics, SubscriptionTopics } from "@fluyappgo/commons";
|
|
2
|
+
import { Listener } from "./baseListener";
|
|
3
|
+
import { BacklogManager } from "../classes/BacklogManager";
|
|
4
|
+
import { MonitorableListener } from "../classes/BacklogMonitor";
|
|
5
|
+
interface Event {
|
|
6
|
+
topic: TicketTopics | AgentTopics | EntityTreeTopics | AgentCrudTopics | MatchTopics | TicketTrackingTopics | AgentTrackingTopics | ManualMatchTopics | MonitorTopics | UserTopics | DeleteTrackingTopics | AuditTopics | NotificationTopics | TicketNoteTopics | TopicsTopics | TicketxTopicsTopics | DeviceTopics | PlanningTopics | WaitingTopics | PaymentsTopics | SubscriptionTopics;
|
|
7
|
+
data: any;
|
|
8
|
+
keyKafka: number;
|
|
9
|
+
groupName: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* EnhancedListener con BacklogManager integrado
|
|
13
|
+
* Extiende baseListener y agrega capacidades de manejo de backlog
|
|
14
|
+
*/
|
|
15
|
+
export declare abstract class EnhancedListener<T extends Event> extends Listener<T> implements MonitorableListener {
|
|
16
|
+
protected backlogManager: BacklogManager;
|
|
17
|
+
protected listenerName: string;
|
|
18
|
+
abstract processMessage(data: T["data"], msg: any): Promise<void>;
|
|
19
|
+
constructor(client: any, listenerName: string, backlogConfig?: any);
|
|
20
|
+
/**
|
|
21
|
+
* Configuración por defecto que puede ser sobrescrita por cada listener
|
|
22
|
+
*/
|
|
23
|
+
protected getDefaultBacklogConfig(): {
|
|
24
|
+
maxConcurrent: number;
|
|
25
|
+
rateLimitMs: number;
|
|
26
|
+
circuitBreakerThreshold: number;
|
|
27
|
+
circuitBreakerResetTime: number;
|
|
28
|
+
maxRetries: number;
|
|
29
|
+
backlogRecoveryBatchSize: number;
|
|
30
|
+
enableBacklogRecovery: boolean;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Override del método onMessage para integrar BacklogManager
|
|
34
|
+
*/
|
|
35
|
+
onMessage(data: T["data"], msg: any): void;
|
|
36
|
+
/**
|
|
37
|
+
* Override del método listen para agregar monitoreo
|
|
38
|
+
*/
|
|
39
|
+
listen(fromBeginning: boolean): void;
|
|
40
|
+
/**
|
|
41
|
+
* Log de estadísticas del BacklogManager
|
|
42
|
+
*/
|
|
43
|
+
private logStats;
|
|
44
|
+
/**
|
|
45
|
+
* Obtener estadísticas del listener
|
|
46
|
+
*/
|
|
47
|
+
getStats(): {
|
|
48
|
+
processed: number;
|
|
49
|
+
failed: number;
|
|
50
|
+
retries: number;
|
|
51
|
+
circuitBreakerTrips: number;
|
|
52
|
+
lastProcessedAt: Date;
|
|
53
|
+
averageProcessingTime: number;
|
|
54
|
+
queueSize: number;
|
|
55
|
+
activeProcessing: number;
|
|
56
|
+
circuitBreakerOpen: boolean;
|
|
57
|
+
config: import("../classes/BacklogManager").BacklogConfig;
|
|
58
|
+
listenerName: string;
|
|
59
|
+
topic: T["topic"];
|
|
60
|
+
groupName: string;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Actualizar configuración del BacklogManager en tiempo real
|
|
64
|
+
*/
|
|
65
|
+
updateBacklogConfig(newConfig: any): void;
|
|
66
|
+
/**
|
|
67
|
+
* Resetear estadísticas
|
|
68
|
+
*/
|
|
69
|
+
resetStats(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Forzar circuit breaker (para debugging)
|
|
72
|
+
*/
|
|
73
|
+
forceCircuitBreaker(open: boolean): void;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
extendStatics(d, b);
|
|
11
|
+
function __() { this.constructor = d; }
|
|
12
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
var __assign = (this && this.__assign) || function () {
|
|
16
|
+
__assign = Object.assign || function(t) {
|
|
17
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
18
|
+
s = arguments[i];
|
|
19
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
20
|
+
t[p] = s[p];
|
|
21
|
+
}
|
|
22
|
+
return t;
|
|
23
|
+
};
|
|
24
|
+
return __assign.apply(this, arguments);
|
|
25
|
+
};
|
|
26
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
27
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
28
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
29
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
30
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
31
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
32
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
36
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
37
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
38
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
39
|
+
function step(op) {
|
|
40
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
41
|
+
while (_) try {
|
|
42
|
+
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;
|
|
43
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
44
|
+
switch (op[0]) {
|
|
45
|
+
case 0: case 1: t = op; break;
|
|
46
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
47
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
48
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
49
|
+
default:
|
|
50
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
51
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
52
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
53
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
54
|
+
if (t[2]) _.ops.pop();
|
|
55
|
+
_.trys.pop(); continue;
|
|
56
|
+
}
|
|
57
|
+
op = body.call(thisArg, _);
|
|
58
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
59
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
63
|
+
exports.EnhancedListener = void 0;
|
|
64
|
+
var baseListener_1 = require("./baseListener");
|
|
65
|
+
var BacklogManager_1 = require("../classes/BacklogManager");
|
|
66
|
+
/**
|
|
67
|
+
* EnhancedListener con BacklogManager integrado
|
|
68
|
+
* Extiende baseListener y agrega capacidades de manejo de backlog
|
|
69
|
+
*/
|
|
70
|
+
var EnhancedListener = /** @class */ (function (_super) {
|
|
71
|
+
__extends(EnhancedListener, _super);
|
|
72
|
+
function EnhancedListener(client, listenerName, backlogConfig) {
|
|
73
|
+
var _this = _super.call(this, client) || this;
|
|
74
|
+
_this.listenerName = listenerName;
|
|
75
|
+
// Configuración específica por tipo de listener
|
|
76
|
+
var defaultConfig = _this.getDefaultBacklogConfig();
|
|
77
|
+
_this.backlogManager = new BacklogManager_1.BacklogManager(__assign(__assign({}, defaultConfig), backlogConfig));
|
|
78
|
+
console.log("\uD83D\uDE80 Enhanced listener " + listenerName + " initialized with BacklogManager");
|
|
79
|
+
return _this;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Configuración por defecto que puede ser sobrescrita por cada listener
|
|
83
|
+
*/
|
|
84
|
+
EnhancedListener.prototype.getDefaultBacklogConfig = function () {
|
|
85
|
+
return {
|
|
86
|
+
maxConcurrent: 3,
|
|
87
|
+
rateLimitMs: 200,
|
|
88
|
+
circuitBreakerThreshold: 5,
|
|
89
|
+
circuitBreakerResetTime: 30000,
|
|
90
|
+
maxRetries: 2,
|
|
91
|
+
backlogRecoveryBatchSize: 25,
|
|
92
|
+
enableBacklogRecovery: true,
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Override del método onMessage para integrar BacklogManager
|
|
97
|
+
*/
|
|
98
|
+
EnhancedListener.prototype.onMessage = function (data, msg) {
|
|
99
|
+
var _this = this;
|
|
100
|
+
// Usar BacklogManager para procesar el mensaje
|
|
101
|
+
this.backlogManager
|
|
102
|
+
.processMessage({ data: data, msg: msg }, function (_a) {
|
|
103
|
+
var data = _a.data, msg = _a.msg;
|
|
104
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
105
|
+
return __generator(this, function (_b) {
|
|
106
|
+
switch (_b.label) {
|
|
107
|
+
case 0: return [4 /*yield*/, this.processMessage(data, msg)];
|
|
108
|
+
case 1:
|
|
109
|
+
_b.sent();
|
|
110
|
+
return [2 /*return*/];
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}, this.listenerName + ":" + this.topic)
|
|
115
|
+
.catch(function (error) {
|
|
116
|
+
console.error("\uD83D\uDCA5 Critical error in " + _this.listenerName + ":", error);
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Override del método listen para agregar monitoreo
|
|
121
|
+
*/
|
|
122
|
+
EnhancedListener.prototype.listen = function (fromBeginning) {
|
|
123
|
+
var _this = this;
|
|
124
|
+
console.log("\uD83C\uDFA7 Starting enhanced listener: " + this.listenerName);
|
|
125
|
+
// Iniciar monitoreo de estadísticas cada 30 segundos
|
|
126
|
+
setInterval(function () {
|
|
127
|
+
_this.logStats();
|
|
128
|
+
}, 30000);
|
|
129
|
+
// Llamar al método padre
|
|
130
|
+
_super.prototype.listen.call(this, fromBeginning);
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Log de estadísticas del BacklogManager
|
|
134
|
+
*/
|
|
135
|
+
EnhancedListener.prototype.logStats = function () {
|
|
136
|
+
var stats = this.backlogManager.getStats();
|
|
137
|
+
if (stats.processed > 0 || stats.failed > 0) {
|
|
138
|
+
console.log("\uD83D\uDCCA " + this.listenerName + " Stats:", {
|
|
139
|
+
processed: stats.processed,
|
|
140
|
+
failed: stats.failed,
|
|
141
|
+
retries: stats.retries,
|
|
142
|
+
queueSize: stats.queueSize,
|
|
143
|
+
activeProcessing: stats.activeProcessing,
|
|
144
|
+
circuitBreakerOpen: stats.circuitBreakerOpen,
|
|
145
|
+
avgProcessingTime: stats.averageProcessingTime.toFixed(0) + "ms",
|
|
146
|
+
successRate: ((stats.processed / (stats.processed + stats.failed)) * 100).toFixed(1) + "%",
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Obtener estadísticas del listener
|
|
152
|
+
*/
|
|
153
|
+
EnhancedListener.prototype.getStats = function () {
|
|
154
|
+
return __assign({ listenerName: this.listenerName, topic: this.topic, groupName: this.groupName }, this.backlogManager.getStats());
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Actualizar configuración del BacklogManager en tiempo real
|
|
158
|
+
*/
|
|
159
|
+
EnhancedListener.prototype.updateBacklogConfig = function (newConfig) {
|
|
160
|
+
this.backlogManager.updateConfig(newConfig);
|
|
161
|
+
console.log("\uD83D\uDD27 " + this.listenerName + " backlog config updated");
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* Resetear estadísticas
|
|
165
|
+
*/
|
|
166
|
+
EnhancedListener.prototype.resetStats = function () {
|
|
167
|
+
this.backlogManager.resetStats();
|
|
168
|
+
console.log("\uD83D\uDD04 " + this.listenerName + " stats reset");
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Forzar circuit breaker (para debugging)
|
|
172
|
+
*/
|
|
173
|
+
EnhancedListener.prototype.forceCircuitBreaker = function (open) {
|
|
174
|
+
if (open) {
|
|
175
|
+
this.backlogManager.forceCircuitBreakerOpen();
|
|
176
|
+
console.log("\uD83D\uDD34 " + this.listenerName + " circuit breaker forced OPEN");
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
this.backlogManager.forceCircuitBreakerClose();
|
|
180
|
+
console.log("\uD83D\uDFE2 " + this.listenerName + " circuit breaker forced CLOSED");
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
return EnhancedListener;
|
|
184
|
+
}(baseListener_1.Listener));
|
|
185
|
+
exports.EnhancedListener = EnhancedListener;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { KafkaMessage } from "kafkajs";
|
|
2
|
+
import { TicketTopics, AgentTopics, EntityTreeTopics, AgentCrudTopics, MatchTopics, TicketTrackingTopics, AgentTrackingTopics, ManualMatchTopics, MonitorTopics, UserTopics, DeleteTrackingTopics, AuditTopics, NotificationTopics, TicketNoteTopics, TopicsTopics, TicketxTopicsTopics, DeviceTopics, PlanningTopics, WaitingTopics, PaymentsTopics, SubscriptionTopics } from "@fluyappgo/commons";
|
|
3
|
+
interface Event {
|
|
4
|
+
topic: TicketTopics | AgentTopics | EntityTreeTopics | AgentCrudTopics | MatchTopics | TicketTrackingTopics | AgentTrackingTopics | ManualMatchTopics | MonitorTopics | UserTopics | DeleteTrackingTopics | AuditTopics | NotificationTopics | TicketNoteTopics | TopicsTopics | TicketxTopicsTopics | DeviceTopics | PlanningTopics | WaitingTopics | PaymentsTopics | SubscriptionTopics;
|
|
5
|
+
data: any;
|
|
6
|
+
keyKafka: number;
|
|
7
|
+
groupName: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function shouldRestart(error: Error): boolean;
|
|
10
|
+
export declare abstract class Listener<T extends Event> {
|
|
11
|
+
abstract topic: T["topic"];
|
|
12
|
+
abstract groupName: string;
|
|
13
|
+
private client;
|
|
14
|
+
abstract onMessage(data: T["data"], msg: any): void;
|
|
15
|
+
constructor(client: any);
|
|
16
|
+
listen(fromBeginning: boolean): void;
|
|
17
|
+
parseMessage(msg: KafkaMessage): any;
|
|
18
|
+
}
|
|
19
|
+
export {};
|