@resolveio/server-lib 20.14.15 → 20.14.17
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/managers/subscription.manager.d.ts +6 -0
- package/managers/subscription.manager.js +179 -61
- package/managers/subscription.manager.js.map +1 -1
- package/managers/websocket.manager.d.ts +0 -1
- package/managers/websocket.manager.js +41 -111
- package/managers/websocket.manager.js.map +1 -1
- package/package.json +1 -1
- package/server-app.d.ts +2 -0
- package/server-app.js +179 -82
- package/server-app.js.map +1 -1
|
@@ -49,6 +49,7 @@ export declare class SubscriptionManager {
|
|
|
49
49
|
private readonly LATENCY_UPDATE_INTERVAL;
|
|
50
50
|
private readonly LATENCY_UPDATE_THRESHOLD_MS;
|
|
51
51
|
private readonly LATENCY_DEBUG_THRESHOLD_MS;
|
|
52
|
+
private readonly PUBLICATION_DEBUG_THRESHOLD_MS;
|
|
52
53
|
private _invalidationDebounceTimers;
|
|
53
54
|
private _invalidationPendingTimestamps;
|
|
54
55
|
private _pendingInvalidations;
|
|
@@ -92,6 +93,11 @@ export declare class SubscriptionManager {
|
|
|
92
93
|
private queueFullResync;
|
|
93
94
|
private fullResyncSubscriptions;
|
|
94
95
|
private tailOpLog;
|
|
96
|
+
private packCachePayload;
|
|
97
|
+
private decodeCachePayload;
|
|
98
|
+
private getCacheBuffer;
|
|
99
|
+
private shouldCachePayload;
|
|
100
|
+
private buffersEqual;
|
|
95
101
|
private processSubscription;
|
|
96
102
|
private sendDataToOne;
|
|
97
103
|
private sendDataToAll;
|
|
@@ -74,6 +74,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
74
74
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
75
75
|
exports.SubscriptionManager = void 0;
|
|
76
76
|
var NodeCache = require("node-cache");
|
|
77
|
+
var msgpackr_1 = require("msgpackr");
|
|
77
78
|
var flag_collection_1 = require("../collections/flag.collection");
|
|
78
79
|
var logged_in_users_collection_1 = require("../collections/logged-in-users.collection");
|
|
79
80
|
var app_status_1 = require("../publications/app-status");
|
|
@@ -160,6 +161,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
160
161
|
// Minimum time difference between two latency updates for the same user
|
|
161
162
|
this.LATENCY_UPDATE_THRESHOLD_MS = 30000;
|
|
162
163
|
this.LATENCY_DEBUG_THRESHOLD_MS = 1000;
|
|
164
|
+
this.PUBLICATION_DEBUG_THRESHOLD_MS = 300;
|
|
163
165
|
// private currentPerfomanceMonitor: CurrentPerformanceMonitor[] = [];
|
|
164
166
|
// private idPerformance: number = 0;
|
|
165
167
|
// private performanceThread;
|
|
@@ -1678,6 +1680,108 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1678
1680
|
});
|
|
1679
1681
|
});
|
|
1680
1682
|
};
|
|
1683
|
+
SubscriptionManager.prototype.packCachePayload = function (data) {
|
|
1684
|
+
if (data === undefined) {
|
|
1685
|
+
return null;
|
|
1686
|
+
}
|
|
1687
|
+
try {
|
|
1688
|
+
var packed = (0, msgpackr_1.pack)(data);
|
|
1689
|
+
return Buffer.isBuffer(packed) ? packed : Buffer.from(packed);
|
|
1690
|
+
}
|
|
1691
|
+
catch (err) {
|
|
1692
|
+
if (this._enableDebug) {
|
|
1693
|
+
console.log(new Date(), 'Sub Cache', 'Pack Failed', (err === null || err === void 0 ? void 0 : err.message) || err);
|
|
1694
|
+
}
|
|
1695
|
+
return null;
|
|
1696
|
+
}
|
|
1697
|
+
};
|
|
1698
|
+
SubscriptionManager.prototype.decodeCachePayload = function (raw) {
|
|
1699
|
+
if (!raw) {
|
|
1700
|
+
return null;
|
|
1701
|
+
}
|
|
1702
|
+
if (Buffer.isBuffer(raw)) {
|
|
1703
|
+
try {
|
|
1704
|
+
return (0, msgpackr_1.unpack)(raw);
|
|
1705
|
+
}
|
|
1706
|
+
catch (err) {
|
|
1707
|
+
if (this._enableDebug) {
|
|
1708
|
+
console.log(new Date(), 'Sub Cache', 'Unpack Failed', (err === null || err === void 0 ? void 0 : err.message) || err);
|
|
1709
|
+
}
|
|
1710
|
+
return null;
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
if (raw instanceof Uint8Array) {
|
|
1714
|
+
try {
|
|
1715
|
+
return (0, msgpackr_1.unpack)(raw);
|
|
1716
|
+
}
|
|
1717
|
+
catch (err) {
|
|
1718
|
+
if (this._enableDebug) {
|
|
1719
|
+
console.log(new Date(), 'Sub Cache', 'Unpack Failed', (err === null || err === void 0 ? void 0 : err.message) || err);
|
|
1720
|
+
}
|
|
1721
|
+
return null;
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
if (raw instanceof ArrayBuffer) {
|
|
1725
|
+
try {
|
|
1726
|
+
return (0, msgpackr_1.unpack)(new Uint8Array(raw));
|
|
1727
|
+
}
|
|
1728
|
+
catch (err) {
|
|
1729
|
+
if (this._enableDebug) {
|
|
1730
|
+
console.log(new Date(), 'Sub Cache', 'Unpack Failed', (err === null || err === void 0 ? void 0 : err.message) || err);
|
|
1731
|
+
}
|
|
1732
|
+
return null;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
// Treat legacy string caches as invalid to avoid JSON parsing in the hot path.
|
|
1736
|
+
if (typeof raw === 'string') {
|
|
1737
|
+
return null;
|
|
1738
|
+
}
|
|
1739
|
+
return raw;
|
|
1740
|
+
};
|
|
1741
|
+
SubscriptionManager.prototype.getCacheBuffer = function (raw) {
|
|
1742
|
+
if (!raw) {
|
|
1743
|
+
return null;
|
|
1744
|
+
}
|
|
1745
|
+
if (Buffer.isBuffer(raw)) {
|
|
1746
|
+
return raw;
|
|
1747
|
+
}
|
|
1748
|
+
if (raw instanceof Uint8Array) {
|
|
1749
|
+
return Buffer.from(raw);
|
|
1750
|
+
}
|
|
1751
|
+
if (raw instanceof ArrayBuffer) {
|
|
1752
|
+
return Buffer.from(new Uint8Array(raw));
|
|
1753
|
+
}
|
|
1754
|
+
return null;
|
|
1755
|
+
};
|
|
1756
|
+
SubscriptionManager.prototype.shouldCachePayload = function (sub, payload) {
|
|
1757
|
+
if (!payload || payload.byteLength >= 1000000) {
|
|
1758
|
+
return false;
|
|
1759
|
+
}
|
|
1760
|
+
if (sub.collections.includes('logs')) {
|
|
1761
|
+
return false;
|
|
1762
|
+
}
|
|
1763
|
+
if (sub.collections.find(function (a) { return a.endsWith('.versions'); })) {
|
|
1764
|
+
return false;
|
|
1765
|
+
}
|
|
1766
|
+
if (sub.collections.find(function (a) { return a.startsWith('monitor-'); })) {
|
|
1767
|
+
return false;
|
|
1768
|
+
}
|
|
1769
|
+
return true;
|
|
1770
|
+
};
|
|
1771
|
+
SubscriptionManager.prototype.buffersEqual = function (a, b) {
|
|
1772
|
+
if (!a || !b) {
|
|
1773
|
+
return false;
|
|
1774
|
+
}
|
|
1775
|
+
if (a.byteLength !== b.byteLength) {
|
|
1776
|
+
return false;
|
|
1777
|
+
}
|
|
1778
|
+
for (var index = 0; index < a.byteLength; index++) {
|
|
1779
|
+
if (a[index] !== b[index]) {
|
|
1780
|
+
return false;
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
return true;
|
|
1784
|
+
};
|
|
1681
1785
|
SubscriptionManager.prototype.processSubscription = function (sub, ws, messageId) {
|
|
1682
1786
|
return __awaiter(this, void 0, void 0, function () {
|
|
1683
1787
|
var cacheData, serverRes, _a;
|
|
@@ -1689,7 +1793,10 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1689
1793
|
_b.label = 1;
|
|
1690
1794
|
case 1:
|
|
1691
1795
|
_b.trys.push([1, 2, , 4]);
|
|
1692
|
-
cacheData =
|
|
1796
|
+
cacheData = this.decodeCachePayload(this._nodeCache.get(sub.cacheId));
|
|
1797
|
+
if (cacheData === null || cacheData === undefined) {
|
|
1798
|
+
throw new Error('cache-miss');
|
|
1799
|
+
}
|
|
1693
1800
|
serverRes = {
|
|
1694
1801
|
messageId: messageId,
|
|
1695
1802
|
hasError: false,
|
|
@@ -1739,12 +1846,13 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1739
1846
|
};
|
|
1740
1847
|
SubscriptionManager.prototype.sendDataToOne = function (ws, messageId, sub, collection, type) {
|
|
1741
1848
|
return __awaiter(this, void 0, void 0, function () {
|
|
1742
|
-
var monitor, dependencySnapshot, res, execution, serverRes, err_1, _a, normalizedError, correlationId, serverRes, errorPayload;
|
|
1849
|
+
var startMs, monitor, dependencySnapshot, res, execution, serverRes, err_1, _a, normalizedError, correlationId, serverRes, errorPayload, durationMs;
|
|
1743
1850
|
var _this = this;
|
|
1744
1851
|
var _b;
|
|
1745
1852
|
return __generator(this, function (_c) {
|
|
1746
1853
|
switch (_c.label) {
|
|
1747
1854
|
case 0:
|
|
1855
|
+
startMs = Date.now();
|
|
1748
1856
|
monitor = this._monitorManagerFunction.startMonitorFunction('User Specific Publication', sub.publication, '', '', sub.subscriptionData);
|
|
1749
1857
|
_c.label = 1;
|
|
1750
1858
|
case 1:
|
|
@@ -1811,7 +1919,22 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1811
1919
|
case 4:
|
|
1812
1920
|
_c.sent();
|
|
1813
1921
|
return [3 /*break*/, 7];
|
|
1814
|
-
case 5:
|
|
1922
|
+
case 5:
|
|
1923
|
+
durationMs = Date.now() - startMs;
|
|
1924
|
+
if (durationMs >= this.PUBLICATION_DEBUG_THRESHOLD_MS) {
|
|
1925
|
+
console.log(new Date(), '[Slow Publication]', {
|
|
1926
|
+
durationMs: durationMs,
|
|
1927
|
+
publication: sub.publication,
|
|
1928
|
+
type: type,
|
|
1929
|
+
collection: collection,
|
|
1930
|
+
userSpecific: true,
|
|
1931
|
+
id_user: ws['id_user'] || null,
|
|
1932
|
+
id_ws: ws['id_socket'] || null,
|
|
1933
|
+
clients: sub.clients ? sub.clients.length : 0,
|
|
1934
|
+
subscriptionData: sub.subscriptionData
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
return [4 /*yield*/, this._monitorManagerFunction.finishMonitorFunction(monitor)];
|
|
1815
1938
|
case 6:
|
|
1816
1939
|
_c.sent();
|
|
1817
1940
|
return [7 /*endfinally*/];
|
|
@@ -1823,7 +1946,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1823
1946
|
// Fetch pub once, send to all clients linked to this pub
|
|
1824
1947
|
SubscriptionManager.prototype.sendDataToAll = function (sub, collection, type) {
|
|
1825
1948
|
return __awaiter(this, void 0, void 0, function () {
|
|
1826
|
-
var subIndex, monitor,
|
|
1949
|
+
var subIndex, startMs, monitor, res, dependencySnapshot, execution, packedRes, shouldCache, cachedBuffer, isSame, _a, _b, client, ws, serverRes, _c, _d, client, ws, serverRes, nodeCacheSize, deleteCount, subArr, zz, err_2, _e, normalizedError, correlationId, _f, _g, client, ws, serverRes, errorPayload, durationMs;
|
|
1827
1950
|
var e_6, _h, e_7, _j, e_8, _k;
|
|
1828
1951
|
var _this = this;
|
|
1829
1952
|
var _l;
|
|
@@ -1841,7 +1964,9 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1841
1964
|
}
|
|
1842
1965
|
return [2 /*return*/];
|
|
1843
1966
|
case 1:
|
|
1967
|
+
startMs = Date.now();
|
|
1844
1968
|
monitor = this._monitorManagerFunction.startMonitorFunction('Publication', sub.publication, '', '', sub.subscriptionData);
|
|
1969
|
+
res = void 0;
|
|
1845
1970
|
dependencySnapshot = void 0;
|
|
1846
1971
|
_m.label = 2;
|
|
1847
1972
|
case 2:
|
|
@@ -1858,69 +1983,51 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1858
1983
|
})];
|
|
1859
1984
|
case 3:
|
|
1860
1985
|
execution = _m.sent();
|
|
1861
|
-
|
|
1986
|
+
res = execution.result;
|
|
1862
1987
|
dependencySnapshot = execution.snapshot;
|
|
1863
1988
|
this.updateSubscriptionDependencies(sub, dependencySnapshot);
|
|
1989
|
+
packedRes = this.packCachePayload(res);
|
|
1990
|
+
shouldCache = this.shouldCachePayload(sub, packedRes);
|
|
1864
1991
|
if (sub.cacheId) {
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
1883
|
-
finally {
|
|
1884
|
-
try {
|
|
1885
|
-
if (_b && !_b.done && (_h = _a.return)) _h.call(_a);
|
|
1992
|
+
cachedBuffer = this.getCacheBuffer(this._nodeCache.get(sub.cacheId));
|
|
1993
|
+
isSame = this.buffersEqual(cachedBuffer, packedRes);
|
|
1994
|
+
if (!isSame) {
|
|
1995
|
+
try {
|
|
1996
|
+
for (_a = __values(sub.clients), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
1997
|
+
client = _b.value;
|
|
1998
|
+
ws = this._websocketManager.getWebSocket(client.id_socket);
|
|
1999
|
+
if (ws && ws.readyState === ws.OPEN) {
|
|
2000
|
+
serverRes = {
|
|
2001
|
+
messageId: client.messageId,
|
|
2002
|
+
hasError: false,
|
|
2003
|
+
data: res
|
|
2004
|
+
};
|
|
2005
|
+
this.sendWS(ws, serverRes);
|
|
1886
2006
|
}
|
|
1887
|
-
finally { if (e_6) throw e_6.error; }
|
|
1888
|
-
}
|
|
1889
|
-
this._nodeCache.del(sub.cacheId);
|
|
1890
|
-
if ((0, common_1.getBinarySize)(JSON.stringify(res_1)) < 1000000 &&
|
|
1891
|
-
!sub.collections.includes('logs') &&
|
|
1892
|
-
!sub.collections.find(function (a) { return a.endsWith('.versions'); }) &&
|
|
1893
|
-
!sub.collections.find(function (a) { return a.startsWith('monitor-'); })) {
|
|
1894
|
-
this._nodeCache.set(sub.cacheId, JSON.stringify(res_1));
|
|
1895
|
-
}
|
|
1896
|
-
else {
|
|
1897
|
-
sub.cacheId = 0;
|
|
1898
2007
|
}
|
|
1899
2008
|
}
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
if (ws && ws.readyState === ws.OPEN) {
|
|
1905
|
-
var serverRes = {
|
|
1906
|
-
messageId: client.messageId,
|
|
1907
|
-
hasError: false,
|
|
1908
|
-
data: res_1
|
|
1909
|
-
};
|
|
1910
|
-
_this.sendWS(ws, serverRes);
|
|
2009
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
2010
|
+
finally {
|
|
2011
|
+
try {
|
|
2012
|
+
if (_b && !_b.done && (_h = _a.return)) _h.call(_a);
|
|
1911
2013
|
}
|
|
1912
|
-
|
|
2014
|
+
finally { if (e_6) throw e_6.error; }
|
|
2015
|
+
}
|
|
1913
2016
|
this._nodeCache.del(sub.cacheId);
|
|
1914
|
-
if (
|
|
1915
|
-
|
|
1916
|
-
!sub.collections.find(function (a) { return a.endsWith('.versions'); }) &&
|
|
1917
|
-
!sub.collections.find(function (a) { return a.startsWith('monitor-'); })) {
|
|
1918
|
-
this._nodeCache.set(sub.cacheId, JSON.stringify(res_1));
|
|
2017
|
+
if (shouldCache) {
|
|
2018
|
+
this._nodeCache.set(sub.cacheId, packedRes);
|
|
1919
2019
|
}
|
|
1920
2020
|
else {
|
|
1921
2021
|
sub.cacheId = 0;
|
|
1922
2022
|
}
|
|
1923
2023
|
}
|
|
2024
|
+
else if (!cachedBuffer && shouldCache) {
|
|
2025
|
+
this._nodeCache.set(sub.cacheId, packedRes);
|
|
2026
|
+
}
|
|
2027
|
+
else if (!shouldCache) {
|
|
2028
|
+
this._nodeCache.del(sub.cacheId);
|
|
2029
|
+
sub.cacheId = 0;
|
|
2030
|
+
}
|
|
1924
2031
|
}
|
|
1925
2032
|
else {
|
|
1926
2033
|
try {
|
|
@@ -1931,7 +2038,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1931
2038
|
serverRes = {
|
|
1932
2039
|
messageId: client.messageId,
|
|
1933
2040
|
hasError: false,
|
|
1934
|
-
data:
|
|
2041
|
+
data: res
|
|
1935
2042
|
};
|
|
1936
2043
|
this.sendWS(ws, serverRes);
|
|
1937
2044
|
}
|
|
@@ -1944,12 +2051,9 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1944
2051
|
}
|
|
1945
2052
|
finally { if (e_7) throw e_7.error; }
|
|
1946
2053
|
}
|
|
1947
|
-
if (
|
|
1948
|
-
!sub.collections.includes('logs') &&
|
|
1949
|
-
!sub.collections.find(function (a) { return a.endsWith('.versions'); }) &&
|
|
1950
|
-
!sub.collections.find(function (a) { return a.startsWith('monitor-'); })) {
|
|
2054
|
+
if (shouldCache) {
|
|
1951
2055
|
sub.cacheId = this._cacheId++;
|
|
1952
|
-
this._nodeCache.set(sub.cacheId,
|
|
2056
|
+
this._nodeCache.set(sub.cacheId, packedRes);
|
|
1953
2057
|
nodeCacheSize = this._nodeCache.getStats().vsize;
|
|
1954
2058
|
if (nodeCacheSize > this._heapLimit) {
|
|
1955
2059
|
deleteCount = 0;
|
|
@@ -2035,7 +2139,21 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2035
2139
|
case 5:
|
|
2036
2140
|
_m.sent();
|
|
2037
2141
|
return [3 /*break*/, 8];
|
|
2038
|
-
case 6:
|
|
2142
|
+
case 6:
|
|
2143
|
+
durationMs = Date.now() - startMs;
|
|
2144
|
+
if (durationMs >= this.PUBLICATION_DEBUG_THRESHOLD_MS) {
|
|
2145
|
+
console.log(new Date(), '[Slow Publication]', {
|
|
2146
|
+
durationMs: durationMs,
|
|
2147
|
+
publication: sub.publication,
|
|
2148
|
+
type: type,
|
|
2149
|
+
collection: collection,
|
|
2150
|
+
userSpecific: false,
|
|
2151
|
+
clients: sub.clients ? sub.clients.length : 0,
|
|
2152
|
+
cacheId: sub.cacheId || 0,
|
|
2153
|
+
subscriptionData: sub.subscriptionData
|
|
2154
|
+
});
|
|
2155
|
+
}
|
|
2156
|
+
return [4 /*yield*/, this._monitorManagerFunction.finishMonitorFunction(monitor)];
|
|
2039
2157
|
case 7:
|
|
2040
2158
|
_m.sent();
|
|
2041
2159
|
return [7 /*endfinally*/];
|