UNPKG

8.9 kBJavaScriptView Raw
1"use strict";
2var __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};
13Object.defineProperty(exports, "__esModule", { value: true });
14exports.enable = exports.mongo330 = exports.mongo3 = exports.mongo2 = void 0;
15// Copyright (c) Microsoft Corporation. All rights reserved.
16// Licensed under the MIT license. See LICENSE file in the project root for details.
17var diagnostic_channel_1 = require("diagnostic-channel");
18var mongodbPatchFunction = function (originalMongo) {
19 var listener = originalMongo.instrument({
20 operationIdGenerator: {
21 next: function () {
22 return diagnostic_channel_1.channel.bindToContext(function (cb) { return cb(); });
23 },
24 },
25 });
26 var eventMap = {};
27 listener.on("started", function (event) {
28 if (eventMap[event.requestId]) {
29 // Note: Mongo can generate 2 completely separate requests
30 // which share the same requestId, if a certain race condition is triggered.
31 // For now, we accept that this can happen and potentially miss or mislabel some events.
32 return;
33 }
34 eventMap[event.requestId] = __assign(__assign({}, event), { time: new Date() });
35 });
36 listener.on("succeeded", function (event) {
37 var startedData = eventMap[event.requestId];
38 if (startedData) {
39 delete eventMap[event.requestId];
40 }
41 if (typeof event.operationId === "function") {
42 event.operationId(function () { return diagnostic_channel_1.channel.publish("mongodb", { startedData: startedData, event: event, succeeded: true }); });
43 }
44 else {
45 // fallback -- correlation will not work here
46 diagnostic_channel_1.channel.publish("mongodb", { startedData: startedData, event: event, succeeded: true });
47 }
48 });
49 listener.on("failed", function (event) {
50 var startedData = eventMap[event.requestId];
51 if (startedData) {
52 delete eventMap[event.requestId];
53 }
54 if (typeof event.operationId === "function") {
55 event.operationId(function () { return diagnostic_channel_1.channel.publish("mongodb", { startedData: startedData, event: event, succeeded: false }); });
56 }
57 else {
58 // fallback -- correlation will not work here
59 diagnostic_channel_1.channel.publish("mongodb", { startedData: startedData, event: event, succeeded: false });
60 }
61 });
62 return originalMongo;
63};
64var mongodb3PatchFunction = function (originalMongo) {
65 var listener = originalMongo.instrument();
66 var eventMap = {};
67 var contextMap = {};
68 listener.on("started", function (event) {
69 if (eventMap[event.requestId]) {
70 // Note: Mongo can generate 2 completely separate requests
71 // which share the same requestId, if a certain race condition is triggered.
72 // For now, we accept that this can happen and potentially miss or mislabel some events.
73 return;
74 }
75 contextMap[event.requestId] = diagnostic_channel_1.channel.bindToContext(function (cb) { return cb(); });
76 eventMap[event.requestId] = __assign(__assign({}, event), { time: new Date() });
77 });
78 listener.on("succeeded", function (event) {
79 var startedData = eventMap[event.requestId];
80 if (startedData) {
81 delete eventMap[event.requestId];
82 }
83 if (typeof event === "object" && typeof contextMap[event.requestId] === "function") {
84 contextMap[event.requestId](function () { return diagnostic_channel_1.channel.publish("mongodb", { startedData: startedData, event: event, succeeded: true }); });
85 delete contextMap[event.requestId];
86 }
87 });
88 listener.on("failed", function (event) {
89 var startedData = eventMap[event.requestId];
90 if (startedData) {
91 delete eventMap[event.requestId];
92 }
93 if (typeof event === "object" && typeof contextMap[event.requestId] === "function") {
94 contextMap[event.requestId](function () { return diagnostic_channel_1.channel.publish("mongodb", { startedData: startedData, event: event, succeeded: false }); });
95 delete contextMap[event.requestId];
96 }
97 });
98 return originalMongo;
99};
100// In mongodb 3.3.0, mongodb-core was merged into mongodb, so the same patching
101// can be used here. this.s.pool was changed to this.s.coreTopology.s.pool
102var mongodbcorePatchFunction = function (originalMongo) {
103 var originalConnect = originalMongo.Server.prototype.connect;
104 originalMongo.Server.prototype.connect = function contextPreservingConnect() {
105 var ret = originalConnect.apply(this, arguments);
106 // Messages sent to mongo progress through a pool
107 // This can result in context getting mixed between different responses
108 // so we wrap the callbacks to restore appropriate state
109 var originalWrite = this.s.coreTopology.s.pool.write;
110 this.s.coreTopology.s.pool.write = function contextPreservingWrite() {
111 var cbidx = typeof arguments[1] === "function" ? 1 : 2;
112 if (typeof arguments[cbidx] === "function") {
113 arguments[cbidx] = diagnostic_channel_1.channel.bindToContext(arguments[cbidx]);
114 }
115 return originalWrite.apply(this, arguments);
116 };
117 // Logout is a special case, it doesn't call the write function but instead
118 // directly calls into connection.write
119 var originalLogout = this.s.coreTopology.s.pool.logout;
120 this.s.coreTopology.s.pool.logout = function contextPreservingLogout() {
121 if (typeof arguments[1] === "function") {
122 arguments[1] = diagnostic_channel_1.channel.bindToContext(arguments[1]);
123 }
124 return originalLogout.apply(this, arguments);
125 };
126 return ret;
127 };
128 return originalMongo;
129};
130var mongodb330PatchFunction = function (originalMongo) {
131 mongodbcorePatchFunction(originalMongo); // apply mongodb-core patches
132 var listener = originalMongo.instrument();
133 var eventMap = {};
134 var contextMap = {};
135 listener.on("started", function (event) {
136 if (eventMap[event.requestId]) {
137 // Note: Mongo can generate 2 completely separate requests
138 // which share the same requestId, if a certain race condition is triggered.
139 // For now, we accept that this can happen and potentially miss or mislabel some events.
140 return;
141 }
142 contextMap[event.requestId] = diagnostic_channel_1.channel.bindToContext(function (cb) { return cb(); });
143 eventMap[event.requestId] = event;
144 });
145 listener.on("succeeded", function (event) {
146 var startedData = eventMap[event.requestId];
147 if (startedData) {
148 delete eventMap[event.requestId];
149 }
150 if (typeof event === "object" && typeof contextMap[event.requestId] === "function") {
151 contextMap[event.requestId](function () { return diagnostic_channel_1.channel.publish("mongodb", { startedData: startedData, event: event, succeeded: true }); });
152 delete contextMap[event.requestId];
153 }
154 });
155 listener.on("failed", function (event) {
156 var startedData = eventMap[event.requestId];
157 if (startedData) {
158 delete eventMap[event.requestId];
159 }
160 if (typeof event === "object" && typeof contextMap[event.requestId] === "function") {
161 contextMap[event.requestId](function () { return diagnostic_channel_1.channel.publish("mongodb", { startedData: startedData, event: event, succeeded: false }); });
162 delete contextMap[event.requestId];
163 }
164 });
165 return originalMongo;
166};
167exports.mongo2 = {
168 versionSpecifier: ">= 2.0.0 <= 3.0.5",
169 patch: mongodbPatchFunction,
170};
171exports.mongo3 = {
172 versionSpecifier: "> 3.0.5 < 3.3.0",
173 patch: mongodb3PatchFunction,
174};
175exports.mongo330 = {
176 versionSpecifier: ">= 3.3.0 < 4.0.0",
177 patch: mongodb330PatchFunction,
178};
179function enable() {
180 diagnostic_channel_1.channel.registerMonkeyPatch("mongodb", exports.mongo2);
181 diagnostic_channel_1.channel.registerMonkeyPatch("mongodb", exports.mongo3);
182 diagnostic_channel_1.channel.registerMonkeyPatch("mongodb", exports.mongo330);
183}
184exports.enable = enable;
185//# sourceMappingURL=mongodb.pub.js.map
\No newline at end of file