Skip to content

Commit 4c530c5

Browse files
authored
fix: track usage of uuid subtype 3 vs 4 COMPASS-9359 (#6943)
1 parent e0286c8 commit 4c530c5

File tree

7 files changed

+118
-19
lines changed

7 files changed

+118
-19
lines changed

packages/compass-components/src/components/bson-value.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ const BinaryValue: React.FunctionComponent<PropsByValueType<'Binary'>> = ({
144144
}
145145
if (value.sub_type === Binary.SUBTYPE_UUID) {
146146
let uuid: string;
147-
148147
try {
149148
// Try to get the pretty hex version of the UUID
150149
uuid = value.toUUID().toString();

packages/compass-crud/src/components/readonly-document.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,13 @@ class ReadonlyDocument extends React.Component<
132132
*/
133133
renderElements() {
134134
return (
135-
<DocumentList.Document
136-
value={this.props.doc}
137-
// Provide extra whitespace for the expand button
138-
extraGutterWidth={spacing[900]}
139-
/>
135+
<>
136+
<DocumentList.Document
137+
value={this.props.doc}
138+
// Provide extra whitespace for the expand button
139+
extraGutterWidth={spacing[900]}
140+
/>
141+
</>
140142
);
141143
}
142144

packages/compass-crud/src/stores/crud-store.spec.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,6 +2296,7 @@ describe('store', function () {
22962296
});
22972297

22982298
describe('fetchDocuments', function () {
2299+
const track = createNoopTrack();
22992300
let findResult: unknown[] = [];
23002301
let csfleMode = 'disabled';
23012302
let find = sinon.stub().callsFake(() => {
@@ -2323,7 +2324,7 @@ describe('store', function () {
23232324
});
23242325

23252326
it('should call find with $bsonSize projection when mongodb version is >= 4.4, not connected to ADF and csfle is disabled', async function () {
2326-
await fetchDocuments(dataService, '5.0.0', false, 'test.test', {});
2327+
await fetchDocuments(dataService, track, '5.0.0', false, 'test.test', {});
23272328
expect(find).to.have.been.calledOnce;
23282329
expect(find.getCall(0))
23292330
.to.have.nested.property('args.2.projection')
@@ -2334,6 +2335,7 @@ describe('store', function () {
23342335
findResult = [{ __size: new Int32(42), __doc: { _id: 1 } }];
23352336
const docs = await fetchDocuments(
23362337
dataService,
2338+
track,
23372339
'4.0.0',
23382340
false,
23392341
'test.test',
@@ -2345,7 +2347,7 @@ describe('store', function () {
23452347
});
23462348

23472349
it('should NOT call find with $bsonSize projection when mongodb version is < 4.4', async function () {
2348-
await fetchDocuments(dataService, '4.0.0', false, 'test.test', {});
2350+
await fetchDocuments(dataService, track, '4.0.0', false, 'test.test', {});
23492351
expect(find).to.have.been.calledOnce;
23502352
expect(find.getCall(0)).to.have.nested.property(
23512353
'args.2.projection',
@@ -2354,7 +2356,7 @@ describe('store', function () {
23542356
});
23552357

23562358
it('should NOT call find with $bsonSize projection when connected to ADF', async function () {
2357-
await fetchDocuments(dataService, '5.0.0', true, 'test.test', {});
2359+
await fetchDocuments(dataService, track, '5.0.0', true, 'test.test', {});
23582360
expect(find).to.have.been.calledOnce;
23592361
expect(find.getCall(0)).to.have.nested.property(
23602362
'args.2.projection',
@@ -2364,7 +2366,7 @@ describe('store', function () {
23642366

23652367
it('should NOT call find with $bsonSize projection when csfle is enabled', async function () {
23662368
csfleMode = 'enabled';
2367-
await fetchDocuments(dataService, '5.0.0', false, 'test.test', {});
2369+
await fetchDocuments(dataService, track, '5.0.0', false, 'test.test', {});
23682370
expect(find).to.have.been.calledOnce;
23692371
expect(find.getCall(0)).to.have.nested.property(
23702372
'args.2.projection',
@@ -2375,6 +2377,7 @@ describe('store', function () {
23752377
it('should keep user projection when provided', async function () {
23762378
await fetchDocuments(
23772379
dataService,
2380+
track,
23782381
'5.0.0',
23792382
false,
23802383
'test.test',
@@ -2399,6 +2402,7 @@ describe('store', function () {
23992402

24002403
const docs = await fetchDocuments(
24012404
dataService,
2405+
track,
24022406
'5.0.0',
24032407
false,
24042408
'test.test',
@@ -2419,7 +2423,14 @@ describe('store', function () {
24192423
find = sinon.stub().rejects(new TypeError('🤷‍♂️'));
24202424

24212425
try {
2422-
await fetchDocuments(dataService, '5.0.0', false, 'test.test', {});
2426+
await fetchDocuments(
2427+
dataService,
2428+
track,
2429+
'5.0.0',
2430+
false,
2431+
'test.test',
2432+
{}
2433+
);
24232434
expect.fail('Expected fetchDocuments to fail with error');
24242435
} catch (err) {
24252436
expect(find).to.have.been.calledOnce;
@@ -2431,7 +2442,14 @@ describe('store', function () {
24312442
find = sinon.stub().rejects(new MongoServerError('Nope'));
24322443

24332444
try {
2434-
await fetchDocuments(dataService, '3.0.0', true, 'test.test', {});
2445+
await fetchDocuments(
2446+
dataService,
2447+
track,
2448+
'3.0.0',
2449+
true,
2450+
'test.test',
2451+
{}
2452+
);
24352453
expect.fail('Expected fetchDocuments to fail with error');
24362454
} catch (err) {
24372455
expect(find).to.have.been.calledOnce;

packages/compass-crud/src/stores/crud-store.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,13 @@ const INITIAL_BULK_UPDATE_TEXT = `{
112112

113113
export const fetchDocuments: (
114114
dataService: DataService,
115+
track: TrackFunction,
115116
serverVersion: string,
116117
isDataLake: boolean,
117118
...args: Parameters<DataService['find']>
118119
) => Promise<HadronDocument[]> = async (
119120
dataService: DataService,
121+
track: TrackFunction,
120122
serverVersion,
121123
isDataLake,
122124
ns,
@@ -145,17 +147,31 @@ export const fetchDocuments: (
145147
};
146148

147149
try {
148-
return (
150+
let uuidSubtype3Count = 0;
151+
let uuidSubtype4Count = 0;
152+
const docs = (
149153
await dataService.find(ns, filter, modifiedOptions, executionOptions)
150154
).map((doc) => {
151155
const { __doc, __size, ...rest } = doc;
156+
let hadronDoc: HadronDocument;
152157
if (__doc && __size && Object.keys(rest).length === 0) {
153-
const hadronDoc = new HadronDocument(__doc);
158+
hadronDoc = new HadronDocument(__doc);
154159
hadronDoc.size = Number(__size);
155-
return hadronDoc;
160+
} else {
161+
hadronDoc = new HadronDocument(doc);
156162
}
157-
return new HadronDocument(doc);
163+
const { subtype3Count, subtype4Count } = hadronDoc.findUUIDs();
164+
uuidSubtype3Count += subtype3Count;
165+
uuidSubtype4Count += subtype4Count;
166+
return hadronDoc;
158167
});
168+
if (uuidSubtype3Count > 0) {
169+
track('UUID Encountered', { subtype: 3, count: uuidSubtype3Count });
170+
}
171+
if (uuidSubtype4Count > 0) {
172+
track('UUID Encountered', { subtype: 4, count: uuidSubtype4Count });
173+
}
174+
return docs;
159175
} catch (err) {
160176
// We are handling all the cases where the size calculating projection might
161177
// not work, but just in case we run into some other environment or use-case
@@ -896,6 +912,7 @@ class CrudStoreImpl
896912
try {
897913
documents = await fetchDocuments(
898914
this.dataService,
915+
this.track,
899916
this.state.version,
900917
this.state.isDataLake,
901918
ns,
@@ -1733,6 +1750,7 @@ class CrudStoreImpl
17331750
),
17341751
fetchDocuments(
17351752
this.dataService,
1753+
this.track,
17361754
this.state.version,
17371755
this.state.isDataLake,
17381756
ns,

packages/compass-telemetry/src/telemetry-events.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2694,6 +2694,14 @@ type CreateIndexButtonClickedEvent = CommonEvent<{
26942694
};
26952695
}>;
26962696

2697+
type UUIDEncounteredEvent = CommonEvent<{
2698+
name: 'UUID Encountered';
2699+
payload: {
2700+
subtype: 3 | 4;
2701+
count: number;
2702+
};
2703+
}>;
2704+
26972705
export type TelemetryEvent =
26982706
| AggregationCanceledEvent
26992707
| AggregationCopiedEvent
@@ -2816,4 +2824,5 @@ export type TelemetryEvent =
28162824
| CumulativeLayoutShiftEvent
28172825
| TimeToFirstByteEvent
28182826
| ExperimentViewedEvent
2819-
| CreateIndexButtonClickedEvent;
2827+
| CreateIndexButtonClickedEvent
2828+
| UUIDEncounteredEvent;

packages/hadron-document/src/document.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type { BSONArray, BSONObject, BSONValue } from './utils';
1212
import { objectToIdiomaticEJSON } from './utils';
1313
import type { HadronEJSONOptions } from './utils';
1414
import { DocumentEvents } from '.';
15-
import type { MongoServerError } from 'mongodb';
15+
import type { Binary, MongoServerError } from 'mongodb';
1616

1717
/**
1818
* The event constant.
@@ -450,6 +450,30 @@ export class Document extends EventEmitter {
450450
}, 0);
451451
}
452452

453+
findUUIDs() {
454+
let subtype4Count = 0;
455+
let subtype3Count = 0;
456+
for (const element of this.elements) {
457+
if (element.currentType === 'Binary') {
458+
if ((element.value as Binary).sub_type === 4) {
459+
subtype4Count++;
460+
}
461+
if ((element.value as Binary).sub_type === 3) {
462+
subtype3Count++;
463+
}
464+
} else if (
465+
element.currentType === 'Object' ||
466+
element.currentType === 'Array'
467+
) {
468+
const { subtype3Count: sub3, subtype4Count: sub4 } =
469+
element.findUUIDs();
470+
subtype3Count += sub3;
471+
subtype4Count += sub4;
472+
}
473+
}
474+
return { subtype3Count, subtype4Count };
475+
}
476+
453477
startEditing(elementId?: string, field?: 'key' | 'value' | 'type'): void {
454478
if (!this.editing) {
455479
this.editing = true;

packages/hadron-document/src/element.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import DateEditor from './editor/date';
1010
import Events from './element-events';
1111
import type Document from './document';
1212
import type { TypeCastTypes } from 'hadron-type-checker';
13-
import type { ObjectId } from 'bson';
13+
import type { Binary, ObjectId } from 'bson';
1414
import type { BSONArray, BSONObject, BSONValue } from './utils';
1515
import { getDefaultValueForType } from './utils';
1616
import { DocumentEvents, ElementEvents } from '.';
@@ -879,6 +879,35 @@ export class Element extends EventEmitter {
879879
);
880880
}
881881

882+
findUUIDs(): { subtype4Count: number; subtype3Count: number } {
883+
let subtype4Count = 0;
884+
let subtype3Count = 0;
885+
886+
if (!this.elements) {
887+
return { subtype4Count, subtype3Count };
888+
}
889+
for (const element of this.elements) {
890+
if (element.currentType === 'Binary') {
891+
if ((element.currentValue as Binary).sub_type === 4) {
892+
subtype4Count++;
893+
}
894+
if ((element.currentValue as Binary).sub_type === 3) {
895+
subtype3Count++;
896+
}
897+
} else if (
898+
element.currentType === 'Object' ||
899+
element.currentType === 'Array'
900+
) {
901+
const { subtype3Count: sub3, subtype4Count: sub4 } =
902+
element.findUUIDs();
903+
subtype3Count += sub3;
904+
subtype4Count += sub4;
905+
}
906+
}
907+
908+
return { subtype4Count, subtype3Count };
909+
}
910+
882911
private emitVisibleElementsChanged(targetElement: Element | Document = this) {
883912
if (targetElement.isRoot()) {
884913
targetElement.emit(DocumentEvents.VisibleElementsChanged, targetElement);

0 commit comments

Comments
 (0)