Skip to content

Commit c6d540e

Browse files
authored
measure some things (#7093)
1 parent c80012b commit c6d540e

File tree

4 files changed

+100
-50
lines changed

4 files changed

+100
-50
lines changed

packages/services/api/src/modules/operations/providers/operations-manager.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import DataLoader from 'dataloader';
22
import { Injectable, Scope } from 'graphql-modules';
33
import LRU from 'lru-cache';
4+
import { traceFn } from '@hive/service-common';
45
import type { DateRange } from '../../../shared/entities';
56
import type { Listify, Optional } from '../../../shared/helpers';
67
import { cache } from '../../../shared/helpers';
@@ -1099,6 +1100,13 @@ export class OperationsManager {
10991100
period: DateRange;
11001101
} & TargetSelector
11011102
>(selector => JSON.stringify(selector))
1103+
@traceFn('OperationManager.countCoordinatesOfTarget', {
1104+
initAttributes: input => ({
1105+
'hive.organization.id': input.organizationId,
1106+
'hive.project.id': input.projectId,
1107+
'hive.target.id': input.targetId,
1108+
}),
1109+
})
11021110
async countCoordinatesOfTarget({
11031111
period,
11041112
targetId: target,

packages/services/api/src/modules/operations/providers/operations-reader.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { addMinutes, format } from 'date-fns';
22
import { Injectable } from 'graphql-modules';
33
import * as z from 'zod';
44
import { UTCDate } from '@date-fns/utc';
5+
import { traceFn } from '@hive/service-common';
56
import type { DateRange } from '../../../shared/entities';
67
import { batch, batchBy } from '../../../shared/helpers';
78
import { Logger } from '../../shared/providers/logger';
@@ -2124,6 +2125,11 @@ export class OperationsReader {
21242125
}));
21252126
}
21262127

2128+
@traceFn('OperationReader.countCoordinatesOfTarget', {
2129+
initAttributes: input => ({
2130+
'hive.target.id': input.target,
2131+
}),
2132+
})
21272133
async countCoordinatesOfTarget({ target, period }: { target: string; period: DateRange }) {
21282134
this.logger.debug('Count coordinates of target. (targetId=%s, period=%o)', target, period);
21292135

packages/services/api/src/modules/schema/utils.ts

Lines changed: 84 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,62 +13,98 @@ import {
1313
} from './module.graphql.mappers';
1414
import stringify from 'fast-json-stable-stringify';
1515
import { ConstDirectiveNode, DEFAULT_DEPRECATION_REASON, DocumentNode, Kind, print } from 'graphql';
16+
import { traceInlineSync } from '@hive/service-common';
1617
import type { DateRange } from '../../shared/entities';
1718
import type { PromiseOrValue } from '../../shared/helpers';
1819
import { OperationsManager } from '../operations/providers/operations-manager';
1920
import { TargetSelector } from '../shared/providers/storage';
2021
import { SuperGraphInformation } from './lib/federation-super-graph';
2122

22-
export function withUsedByClients<
23-
T extends {
24-
isUsed: boolean;
25-
},
26-
>(
27-
input: Record<string, T>,
28-
deps: {
29-
operationsManager: OperationsManager;
30-
selector: TargetSelector;
31-
period: DateRange;
32-
typename: string;
33-
},
34-
): Record<
35-
string,
36-
T & {
37-
usedByClients: () => PromiseOrValue<Array<string>>;
38-
period: DateRange;
39-
organizationId: string;
40-
projectId: string;
41-
targetId: string;
42-
typename: string;
43-
}
44-
> {
45-
return Object.fromEntries(
46-
Object.entries(input).map(([schemaCoordinate, record]) => [
47-
schemaCoordinate,
48-
{
49-
selector: deps.selector,
50-
period: deps.period,
51-
typename: deps.typename,
52-
organizationId: deps.selector.organizationId,
53-
projectId: deps.selector.projectId,
54-
targetId: deps.selector.targetId,
55-
...record,
56-
usedByClients() {
57-
if (record.isUsed === false) {
58-
return [];
59-
}
23+
export const withUsedByClients = traceInlineSync(
24+
'withUsedByClients',
25+
{},
26+
function withUsedByClients<
27+
T extends {
28+
isUsed: boolean;
29+
},
30+
>(
31+
input: Record<string, T>,
32+
deps: {
33+
operationsManager: OperationsManager;
34+
selector: TargetSelector;
35+
period: DateRange;
36+
typename: string;
37+
},
38+
): Record<
39+
string,
40+
T & {
41+
usedByClients: () => PromiseOrValue<Array<string>>;
42+
period: DateRange;
43+
organizationId: string;
44+
projectId: string;
45+
targetId: string;
46+
typename: string;
47+
}
48+
> {
49+
// input can contain ALLLLLLLLLL the schema coordinates.
50+
// in order to be more efficient we lazily create the properties here as we could accidentially create way tooo much stuff!
51+
return new Proxy(input, {
52+
get(target, property, receiver) {
53+
if (
54+
typeof property !== 'string' ||
55+
/** some code might check if this is a promise :D */
56+
property === 'then'
57+
) {
58+
return Reflect.get(target, property, receiver);
59+
}
6060

61-
// It's using DataLoader under the hood so it's safe to call it multiple times for different coordinates
62-
return deps.operationsManager.getClientNamesPerCoordinateOfType({
63-
...deps.selector,
64-
period: deps.period,
65-
schemaCoordinate,
66-
});
67-
},
61+
// Guard against trying to look up properties that do not belong to this typename!
62+
if (!property.startsWith(deps.typename)) {
63+
return undefined;
64+
}
65+
66+
const schemaCoordinate = property;
67+
const record = input[property];
68+
69+
if (!record) {
70+
return undefined;
71+
}
72+
73+
return {
74+
selector: deps.selector,
75+
period: deps.period,
76+
typename: deps.typename,
77+
organizationId: deps.selector.organizationId,
78+
projectId: deps.selector.projectId,
79+
targetId: deps.selector.targetId,
80+
...record,
81+
usedByClients() {
82+
if (record.isUsed === false) {
83+
return [];
84+
}
85+
86+
// It's using DataLoader under the hood so it's safe to call it multiple times for different coordinates
87+
return deps.operationsManager.getClientNamesPerCoordinateOfType({
88+
...deps.selector,
89+
period: deps.period,
90+
schemaCoordinate,
91+
});
92+
},
93+
};
6894
},
69-
]),
70-
);
71-
}
95+
}) as Record<
96+
string,
97+
T & {
98+
usedByClients: () => PromiseOrValue<Array<string>>;
99+
period: DateRange;
100+
organizationId: string;
101+
projectId: string;
102+
targetId: string;
103+
typename: string;
104+
}
105+
>;
106+
},
107+
);
72108

73109
function deprecationReasonFromDirectives(directives: readonly ConstDirectiveNode[] | undefined) {
74110
if (!directives) {

packages/services/service-common/src/tracing.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,8 @@ export function traceFn<This extends Object, TArgs extends any[], TResult>(
473473
options?: FunctionTraceOptions<TArgs, Awaited<TResult>>,
474474
) {
475475
return function (
476-
target: This,
477-
key: PropertyKey,
476+
_target: This,
477+
_key: PropertyKey,
478478
descriptor: TypedPropertyDescriptor<(...args: TArgs) => TResult>,
479479
) {
480480
const originalMethod = descriptor.value;

0 commit comments

Comments
 (0)