kuzzle 2.21.0 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -42,10 +42,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
42
42
  __setModuleDefault(result, mod);
43
43
  return result;
44
44
  };
45
+ var __importDefault = (this && this.__importDefault) || function (mod) {
46
+ return (mod && mod.__esModule) ? mod : { "default": mod };
47
+ };
45
48
  Object.defineProperty(exports, "__esModule", { value: true });
46
49
  exports.DebugController = void 0;
47
50
  const baseController_1 = require("./baseController");
48
51
  const kerror = __importStar(require("../../kerror"));
52
+ const get_1 = __importDefault(require("lodash/get"));
49
53
  /**
50
54
  * @class DebugController
51
55
  */
@@ -70,12 +74,18 @@ class DebugController extends baseController_1.NativeController {
70
74
  * Connect the debugger
71
75
  */
72
76
  async enable() {
77
+ if (!(0, get_1.default)(global.kuzzle.config, "security.debug.native_debug_protocol")) {
78
+ throw kerror.get("core", "debugger", "native_debug_protocol_usage_denied");
79
+ }
73
80
  await global.kuzzle.ask("core:debugger:enable");
74
81
  }
75
82
  /**
76
83
  * Disconnect the debugger and clears all the events listeners
77
84
  */
78
85
  async disable() {
86
+ if (!(0, get_1.default)(global.kuzzle.config, "security.debug.native_debug_protocol")) {
87
+ throw kerror.get("core", "debugger", "native_debug_protocol_usage_denied");
88
+ }
79
89
  await global.kuzzle.ask("core:debugger:disable");
80
90
  }
81
91
  /**
@@ -83,6 +93,9 @@ class DebugController extends baseController_1.NativeController {
83
93
  * See: https://chromedevtools.github.io/devtools-protocol/v8/
84
94
  */
85
95
  async post(request) {
96
+ if (!(0, get_1.default)(global.kuzzle.config, "security.debug.native_debug_protocol")) {
97
+ throw kerror.get("core", "debugger", "native_debug_protocol_usage_denied");
98
+ }
86
99
  const method = request.getBodyString("method");
87
100
  const params = request.getBodyObject("params", {});
88
101
  return global.kuzzle.ask("core:debugger:post", method, params);
@@ -92,6 +105,9 @@ class DebugController extends baseController_1.NativeController {
92
105
  * See events from: https://chromedevtools.github.io/devtools-protocol/v8/
93
106
  */
94
107
  async addListener(request) {
108
+ if (!(0, get_1.default)(global.kuzzle.config, "security.debug.native_debug_protocol")) {
109
+ throw kerror.get("core", "debugger", "native_debug_protocol_usage_denied");
110
+ }
95
111
  if (request.context.connection.protocol !== "websocket") {
96
112
  throw kerror.get("api", "assert", "unsupported_protocol", request.context.connection.protocol, "debug:addListener");
97
113
  }
@@ -102,6 +118,9 @@ class DebugController extends baseController_1.NativeController {
102
118
  * Remove the websocket connection from the events' listeners
103
119
  */
104
120
  async removeListener(request) {
121
+ if (!(0, get_1.default)(global.kuzzle.config, "security.debug.native_debug_protocol")) {
122
+ throw kerror.get("core", "debugger", "native_debug_protocol_usage_denied");
123
+ }
105
124
  if (request.context.connection.protocol !== "websocket") {
106
125
  throw kerror.get("api", "assert", "unsupported_protocol", request.context.connection.protocol, "debug:removeListener");
107
126
  }
package/lib/api/funnel.js CHANGED
@@ -51,6 +51,7 @@ const debug = require("../util/debug")("kuzzle:funnel");
51
51
  const processError = kerror.wrap("api", "process");
52
52
  const { has } = require("../util/safeObject");
53
53
  const { HttpStream } = require("../types");
54
+ const get = require("lodash/get");
54
55
 
55
56
  // Actions of the auth controller that does not necessite to verify the token
56
57
  // when cookie auth is active
@@ -179,6 +180,12 @@ class Funnel {
179
180
  throw processError.get("not_enough_nodes");
180
181
  }
181
182
 
183
+ const isRequestFromDebugSession = get(
184
+ request,
185
+ "context.connection.misc.internal.debugSession",
186
+ false
187
+ );
188
+
182
189
  if (this.overloaded) {
183
190
  const now = Date.now();
184
191
 
@@ -226,7 +233,8 @@ class Funnel {
226
233
  */
227
234
  if (
228
235
  this.pendingRequestsQueue.length >=
229
- global.kuzzle.config.limits.requestsBufferSize
236
+ global.kuzzle.config.limits.requestsBufferSize &&
237
+ !isRequestFromDebugSession
230
238
  ) {
231
239
  const error = processError.get("overloaded");
232
240
  global.kuzzle.emit("log:error", error);
@@ -239,7 +247,13 @@ class Funnel {
239
247
  request.internalId,
240
248
  new PendingRequest(request, fn, context)
241
249
  );
242
- this.pendingRequestsQueue.push(request.internalId);
250
+
251
+ if (isRequestFromDebugSession) {
252
+ // Push at the front to prioritize debug requests
253
+ this.pendingRequestsQueue.unshift(request.internalId);
254
+ } else {
255
+ this.pendingRequestsQueue.push(request.internalId);
256
+ }
243
257
 
244
258
  if (!this.overloaded) {
245
259
  this.overloaded = true;
@@ -256,6 +256,15 @@ class ClusterNode {
256
256
  */
257
257
  preventEviction(evictionPrevented) {
258
258
  this.publisher.sendNodePreventEviction(evictionPrevented);
259
+ // This node is subscribed to the other node and might not receive their heartbeat while debugging
260
+ // so this node should not have the responsability of evicting others when his own eviction is prevented
261
+ // when debugging.
262
+ // Otherwise when recovering from a debug session, all the other nodes will be evicted.
263
+ for (const subscriber of this.remoteNodes.values()) {
264
+ subscriber.handleNodePreventEviction({
265
+ evictionPrevented,
266
+ });
267
+ }
259
268
  }
260
269
 
261
270
  /**
@@ -680,7 +680,15 @@ class ClusterSubscriber {
680
680
  * to recover, otherwise we evict it from the cluster.
681
681
  */
682
682
  async checkHeartbeat() {
683
- if (this.state === stateEnum.EVICTED || this.remoteNodeEvictionPrevented) {
683
+ if (this.remoteNodeEvictionPrevented) {
684
+ // Fake the heartbeat while the node eviction prevention is enabled
685
+ // otherwise when the node eviction prevention is disabled
686
+ // the node will be evicted if it did not send a heartbeat before disabling the protection.
687
+ this.lastHeartbeat = Date.now();
688
+ return;
689
+ }
690
+
691
+ if (this.state === stateEnum.EVICTED) {
684
692
  return;
685
693
  }
686
694
 
@@ -29,6 +29,10 @@ class IDCardRenewer {
29
29
  const redisConf = config.redis || {};
30
30
  await this.initRedis(redisConf.config, redisConf.name);
31
31
  } catch (error) {
32
+ // eslint-disable-next-line no-console
33
+ console.error(
34
+ `Failed to connect to redis, could not refresh ID card: ${error.message}`
35
+ );
32
36
  this.parentPort.postMessage({
33
37
  error: `Failed to connect to redis, could not refresh ID card: ${error.message}`,
34
38
  });
@@ -1,5 +1,5 @@
1
1
  import { EmbeddedSDK } from "../shared/sdk/embeddedSdk";
2
- import { EventDefinition, JSONObject } from "../../../index";
2
+ import { BackendSubscription, EventDefinition, JSONObject } from "../../../index";
3
3
  import { BackendCluster, BackendConfig, BackendController, BackendHook, BackendImport, BackendPipe, BackendPlugin, BackendStorage, BackendVault, BackendOpenApi, InternalLogger, BackendErrors } from "./index";
4
4
  export declare class Backend {
5
5
  private _kuzzle;
@@ -121,6 +121,7 @@ export declare class Backend {
121
121
  * Standard errors
122
122
  */
123
123
  errors: BackendErrors;
124
+ subscription: BackendSubscription;
124
125
  /**
125
126
  * @deprecated
126
127
  *
@@ -51,7 +51,8 @@ const fs_1 = __importDefault(require("fs"));
51
51
  const kuzzle_1 = __importDefault(require("../../kuzzle"));
52
52
  const embeddedSdk_1 = require("../shared/sdk/embeddedSdk");
53
53
  const kerror = __importStar(require("../../kerror"));
54
- const index_1 = require("./index");
54
+ const index_1 = require("../../../index");
55
+ const index_2 = require("./index");
55
56
  const assertionError = kerror.wrap("plugin", "assert");
56
57
  const runtimeError = kerror.wrap("plugin", "runtime");
57
58
  let _app = null;
@@ -139,18 +140,19 @@ class Backend {
139
140
  // Silent if no version can be found
140
141
  }
141
142
  global.app = this;
142
- this.pipe = new index_1.BackendPipe(this);
143
- this.hook = new index_1.BackendHook(this);
144
- this.config = new index_1.BackendConfig(this);
145
- this.vault = new index_1.BackendVault(this);
146
- this.controller = new index_1.BackendController(this);
147
- this.plugin = new index_1.BackendPlugin(this);
148
- this.storage = new index_1.BackendStorage(this);
149
- this.import = new index_1.BackendImport(this);
150
- this.log = new index_1.InternalLogger(this);
151
- this.cluster = new index_1.BackendCluster();
152
- this.openApi = new index_1.BackendOpenApi(this);
153
- this.errors = new index_1.BackendErrors(this);
143
+ this.pipe = new index_2.BackendPipe(this);
144
+ this.hook = new index_2.BackendHook(this);
145
+ this.config = new index_2.BackendConfig(this);
146
+ this.vault = new index_2.BackendVault(this);
147
+ this.controller = new index_2.BackendController(this);
148
+ this.plugin = new index_2.BackendPlugin(this);
149
+ this.storage = new index_2.BackendStorage(this);
150
+ this.import = new index_2.BackendImport(this);
151
+ this.log = new index_2.InternalLogger(this);
152
+ this.cluster = new index_2.BackendCluster();
153
+ this.openApi = new index_2.BackendOpenApi(this);
154
+ this.errors = new index_2.BackendErrors(this);
155
+ this.subscription = new index_1.BackendSubscription(this);
154
156
  this.kerror = kerror;
155
157
  try {
156
158
  this.commit = this._readCommit();
@@ -0,0 +1,25 @@
1
+ import { JSONObject } from "kuzzle-sdk";
2
+ import { Connection } from "../../api/request";
3
+ import { ApplicationManager } from "./index";
4
+ export declare class BackendSubscription extends ApplicationManager {
5
+ /**
6
+ * Registers a new realtime subscription on the specified connection
7
+ *
8
+ * @param connection Connection to register the subscription on
9
+ * @param index Index name
10
+ * @param collection Collection name
11
+ * @param filters Subscription filters
12
+ * @param options.volatile Volatile data
13
+ * @param options.scope Subscription scope
14
+ * @param options.users Option for users notifications
15
+ */
16
+ add(connection: Connection, index: string, collection: string, filters: JSONObject, { volatile, scope, users, }?: {
17
+ volatile?: JSONObject;
18
+ scope?: "in" | "out" | "all" | "none";
19
+ users?: "in" | "out" | "all" | "none";
20
+ }): Promise<{
21
+ roomId: string;
22
+ channel: string;
23
+ }>;
24
+ remove(connection: Connection, roomId: string): Promise<void>;
25
+ }
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ /*
3
+ * Kuzzle, a backend software, self-hostable and ready to use
4
+ * to power modern apps
5
+ *
6
+ * Copyright 2015-2022 Kuzzle
7
+ * mailto: support AT kuzzle.io
8
+ * website: http://kuzzle.io
9
+ *
10
+ * Licensed under the Apache License, Version 2.0 (the "License");
11
+ * you may not use this file except in compliance with the License.
12
+ * You may obtain a copy of the License at
13
+ *
14
+ * https://www.apache.org/licenses/LICENSE-2.0
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
+ */
22
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ var desc = Object.getOwnPropertyDescriptor(m, k);
25
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
26
+ desc = { enumerable: true, get: function() { return m[k]; } };
27
+ }
28
+ Object.defineProperty(o, k2, desc);
29
+ }) : (function(o, m, k, k2) {
30
+ if (k2 === undefined) k2 = k;
31
+ o[k2] = m[k];
32
+ }));
33
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
34
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
35
+ }) : function(o, v) {
36
+ o["default"] = v;
37
+ });
38
+ var __importStar = (this && this.__importStar) || function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.BackendSubscription = void 0;
47
+ const request_1 = require("../../api/request");
48
+ const kerror = __importStar(require("../../kerror"));
49
+ const index_1 = require("./index");
50
+ const runtimeError = kerror.wrap("plugin", "runtime");
51
+ class BackendSubscription extends index_1.ApplicationManager {
52
+ /**
53
+ * Registers a new realtime subscription on the specified connection
54
+ *
55
+ * @param connection Connection to register the subscription on
56
+ * @param index Index name
57
+ * @param collection Collection name
58
+ * @param filters Subscription filters
59
+ * @param options.volatile Volatile data
60
+ * @param options.scope Subscription scope
61
+ * @param options.users Option for users notifications
62
+ */
63
+ async add(connection, index, collection, filters, { volatile, scope, users, } = {}) {
64
+ if (!this._application.started) {
65
+ throw runtimeError.get("unavailable_before_start", "subscriptions.add");
66
+ }
67
+ const subscriptionRequest = new request_1.KuzzleRequest({
68
+ action: "subscribe",
69
+ body: filters,
70
+ collection,
71
+ controller: "realtime",
72
+ index,
73
+ scope,
74
+ users,
75
+ }, {
76
+ connectionId: connection.id,
77
+ volatile,
78
+ });
79
+ const { channel, roomId } = await global.kuzzle.ask("core:realtime:subscribe", subscriptionRequest);
80
+ return { channel, roomId };
81
+ }
82
+ async remove(connection, roomId) {
83
+ if (!this._application.started) {
84
+ throw runtimeError.get("unavailable_before_start", "subscriptions.remove");
85
+ }
86
+ await global.kuzzle.ask("core:realtime:unsubscribe", connection.id, roomId);
87
+ }
88
+ }
89
+ exports.BackendSubscription = BackendSubscription;
90
+ //# sourceMappingURL=backendSubscription.js.map
@@ -12,3 +12,4 @@ export * from "./backendVault";
12
12
  export * from "./backendOpenApi";
13
13
  export * from "./internalLogger";
14
14
  export * from "./backendErrors";
15
+ export * from "./backendSubscription";
@@ -28,4 +28,5 @@ __exportStar(require("./backendVault"), exports);
28
28
  __exportStar(require("./backendOpenApi"), exports);
29
29
  __exportStar(require("./internalLogger"), exports);
30
30
  __exportStar(require("./backendErrors"), exports);
31
+ __exportStar(require("./backendSubscription"), exports);
31
32
  //# sourceMappingURL=index.js.map
@@ -6,6 +6,7 @@ export declare class KuzzleDebugger {
6
6
  * Map<eventName, Set<connectionId>>
7
7
  */
8
8
  private events;
9
+ private httpWsProtocol?;
9
10
  init(): Promise<void>;
10
11
  registerAsks(): Promise<void>;
11
12
  /**
@@ -29,7 +29,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.KuzzleDebugger = void 0;
30
30
  const inspector_1 = __importDefault(require("inspector"));
31
31
  const kerror = __importStar(require("../../kerror"));
32
- const get_1 = __importDefault(require("lodash/get"));
33
32
  const DEBUGGER_EVENT = "kuzzle-debugger-event";
34
33
  class KuzzleDebugger {
35
34
  constructor() {
@@ -40,6 +39,7 @@ class KuzzleDebugger {
40
39
  this.events = new Map();
41
40
  }
42
41
  async init() {
42
+ this.httpWsProtocol = global.kuzzle.entryPoint.protocols.get("websocket");
43
43
  this.inspector = new inspector_1.default.Session();
44
44
  // Remove connection id from the list of listeners for each event
45
45
  global.kuzzle.on("connection:remove", (connectionId) => {
@@ -100,6 +100,17 @@ class KuzzleDebugger {
100
100
  this.inspector.disconnect();
101
101
  this.debuggerStatus = false;
102
102
  await global.kuzzle.ask("cluster:node:preventEviction", false);
103
+ // Disable debug mode for all connected sockets that still have listeners
104
+ if (this.httpWsProtocol) {
105
+ for (const eventName of this.events.keys()) {
106
+ for (const connectionId of this.events.get(eventName)) {
107
+ const socket = this.httpWsProtocol.socketByConnectionId.get(connectionId);
108
+ if (socket) {
109
+ socket.internal.debugSession = false;
110
+ }
111
+ }
112
+ }
113
+ }
103
114
  this.events.clear();
104
115
  }
105
116
  /**
@@ -110,16 +121,33 @@ class KuzzleDebugger {
110
121
  if (!this.debuggerStatus) {
111
122
  throw kerror.get("core", "debugger", "not_enabled");
112
123
  }
113
- if (!(0, get_1.default)(global.kuzzle.config, "security.debug.native_debug_protocol")) {
114
- throw kerror.get("core", "debugger", "native_debug_protocol_usage_denied");
115
- }
116
- // Always disable report progress because this params causes a segfault.
124
+ // Always disable report progress because this parameter causes a segfault.
117
125
  // The reason this happens is because the inspector is running inside the same thread
118
- // as the Kuzzle Process and reportProgress forces the inspector to send events
119
- // to the main thread, while it is being inspected by the HeapProfiler, which causes javascript code
120
- // to be executed as the HeapProfiler is running, which causes a segfault.
126
+ // as the Kuzzle Process and reportProgress forces the inspector to call function in the JS Heap
127
+ // while it is being inspected by the HeapProfiler, which causes a segfault.
121
128
  // See: https://github.com/nodejs/node/issues/44634
122
- params.reportProgress = false;
129
+ if (params.reportProgress) {
130
+ // We need to send a fake HeapProfiler.reportHeapSnapshotProgress event
131
+ // to the inspector to make Chrome think that the HeapProfiler is done
132
+ // otherwise, even though the Chrome Inspector did receive the whole snapshot, it will not be parsed.
133
+ //
134
+ // Chrome inspector is waiting for a HeapProfiler.reportHeapSnapshotProgress event with the finished property set to true
135
+ // The `done` and `total` properties are only used to show a progress bar, so there are not important.
136
+ // Sending this event before the HeapProfiler.addHeapSnapshotChunk event will not cause any problem,
137
+ // in fact, Chrome always do that when taking a snapshot, it receives the HeapProfiler.reportHeapSnapshotProgress event
138
+ // before the HeapProfiler.addHeapSnapshotChunk event.
139
+ // So this will have no impact and when receiving the HeapProfiler.addHeapSnapshotChunk event, Chrome will wait to receive
140
+ // a complete snapshot before parsing it if it has received the HeapProfiler.reportHeapSnapshotProgress event with the finished property set to true before.
141
+ this.inspector.emit("inspectorNotification", {
142
+ method: "HeapProfiler.reportHeapSnapshotProgress",
143
+ params: {
144
+ done: 0,
145
+ finished: true,
146
+ total: 0,
147
+ },
148
+ });
149
+ params.reportProgress = false;
150
+ }
123
151
  return this.inspectorPost(method, params);
124
152
  }
125
153
  /**
@@ -130,6 +158,17 @@ class KuzzleDebugger {
130
158
  if (!this.debuggerStatus) {
131
159
  throw kerror.get("core", "debugger", "not_enabled");
132
160
  }
161
+ if (this.httpWsProtocol) {
162
+ const socket = this.httpWsProtocol.socketByConnectionId.get(connectionId);
163
+ if (socket) {
164
+ /**
165
+ * Mark the socket as a debugging socket
166
+ * this will bypass some limitations like the max pressure buffer size,
167
+ * which could end the connection when the debugger is sending a lot of data.
168
+ */
169
+ socket.internal.debugSession = true;
170
+ }
171
+ }
133
172
  let listeners = this.events.get(event);
134
173
  if (!listeners) {
135
174
  listeners = new Set();
@@ -148,6 +187,28 @@ class KuzzleDebugger {
148
187
  if (listeners) {
149
188
  listeners.delete(connectionId);
150
189
  }
190
+ if (!this.httpWsProtocol) {
191
+ return;
192
+ }
193
+ const socket = this.httpWsProtocol.socketByConnectionId.get(connectionId);
194
+ if (!socket) {
195
+ return;
196
+ }
197
+ let removeDebugSessionMarker = true;
198
+ /**
199
+ * If the connection doesn't listen to any other events
200
+ * we can remove the debugSession marker
201
+ */
202
+ for (const eventName of this.events.keys()) {
203
+ const eventListener = this.events.get(eventName);
204
+ if (eventListener && eventListener.has(connectionId)) {
205
+ removeDebugSessionMarker = false;
206
+ break;
207
+ }
208
+ }
209
+ if (removeDebugSessionMarker) {
210
+ socket.internal.debugSession = false;
211
+ }
151
212
  }
152
213
  /**
153
214
  * Execute a method using the Chrome Debug Protocol
@@ -31,10 +31,11 @@ const uuid = require("uuid");
31
31
  * @param {object} [headers] - Optional extra key-value object. I.e., for http, will receive the request headers
32
32
  */
33
33
  class ClientConnection {
34
- constructor(protocol, ips, headers = null) {
34
+ constructor(protocol, ips, headers = null, internal = null) {
35
35
  this.id = uuid.v4();
36
36
  this.protocol = protocol;
37
37
  this.headers = {};
38
+ this.internal = {};
38
39
 
39
40
  if (!Array.isArray(ips)) {
40
41
  throw new TypeError(`Expected ips to be an Array, got ${typeof ips}`);
@@ -45,6 +46,10 @@ class ClientConnection {
45
46
  this.headers = headers;
46
47
  }
47
48
 
49
+ if (isPlainObject(internal)) {
50
+ this.internal = internal;
51
+ }
52
+
48
53
  Object.freeze(this);
49
54
  }
50
55
  }
@@ -282,6 +282,7 @@ class HttpWsProtocol extends Protocol {
282
282
  res.upgrade(
283
283
  {
284
284
  headers,
285
+ internal: {},
285
286
  },
286
287
  req.getHeader("sec-websocket-key"),
287
288
  req.getHeader("sec-websocket-protocol"),
@@ -292,7 +293,12 @@ class HttpWsProtocol extends Protocol {
292
293
 
293
294
  wsOnOpenHandler(socket) {
294
295
  const ip = Buffer.from(socket.getRemoteAddressAsText()).toString();
295
- const connection = new ClientConnection(this.name, [ip], socket.headers);
296
+ const connection = new ClientConnection(
297
+ this.name,
298
+ [ip],
299
+ socket.headers,
300
+ socket.internal
301
+ );
296
302
 
297
303
  this.entryPoint.newConnection(connection);
298
304
  this.connectionBySocket.set(socket, connection);
@@ -457,8 +463,17 @@ class HttpWsProtocol extends Protocol {
457
463
  const buffer = this.backpressureBuffer.get(socket);
458
464
  buffer.push(payload);
459
465
 
460
- // Client socket too slow: we need to close it
461
- if (buffer.length > WS_BACKPRESSURE_BUFFER_MAX_LENGTH) {
466
+ /**
467
+ * Client socket too slow: we need to close it
468
+ *
469
+ * If the socket is marked as a debugSession, we don't close it
470
+ * the debugger might send a lot of messages and we don't want to
471
+ * loose the connection while debugging and loose important information.
472
+ */
473
+ if (
474
+ !socket.internal.debugSession &&
475
+ buffer.length > WS_BACKPRESSURE_BUFFER_MAX_LENGTH
476
+ ) {
462
477
  socket.end(WS_FORCED_TERMINATION_CODE, WS_BACKPRESSURE_MESSAGE);
463
478
  }
464
479
  }
@@ -148,7 +148,6 @@ class Kuzzle extends kuzzleEventEmitter_1.default {
148
148
  regExpEngine: this.config.realtime.pcreSupport ? "js" : "re2",
149
149
  seed: this.config.internal.hash.seed,
150
150
  });
151
- await this.debugger.init();
152
151
  await new cacheEngine_1.default().init();
153
152
  await new storageEngine_1.default().init();
154
153
  await new realtime_1.default().init();
@@ -167,6 +166,7 @@ class Kuzzle extends kuzzleEventEmitter_1.default {
167
166
  // must be initialized before plugins to allow API requests from plugins
168
167
  // before opening connections to external users
169
168
  await this.entryPoint.init();
169
+ await this.debugger.init();
170
170
  this.pluginsManager.application = application;
171
171
  const pluginImports = await this.pluginsManager.init(options.plugins);
172
172
  this.log.info(`[✔] Successfully loaded ${this.pluginsManager.loadedPlugins.length} plugins: ${this.pluginsManager.loadedPlugins.join(", ")}`);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kuzzle",
3
3
  "author": "The Kuzzle Team <support@kuzzle.io>",
4
- "version": "2.21.0",
4
+ "version": "2.22.0",
5
5
  "description": "Kuzzle is an open-source solution that handles all the data management through a secured API, with a large choice of protocols.",
6
6
  "bin": "bin/start-kuzzle-server",
7
7
  "scripts": {