Skip to content

Commit

Permalink
Clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
Joshua Segaran committed May 21, 2020
1 parent 67a7d38 commit 24b4141
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 109 deletions.
16 changes: 8 additions & 8 deletions packages/apollo-engine-reporting/src/ContextualizedStats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,28 +162,28 @@ export class ContextualizedStats {
const queryLatencyStats = this.queryLatencyStats;
const perTypeStat: { [k: string]: TypeStatProto } = Object.create(null);
for (const type of this.perTypeStat.keys()) {
const perFieldStat: { [k: string]: FieldStatProto | null } = Object.create(null);
const fieldMap = this.perTypeStat.get(type)
const perFieldStat: {
[k: string]: FieldStatProto | null;
} = Object.create(null);
const fieldMap = this.perTypeStat.get(type);

// Should never hit this since we check it is in the list of keys
if (!fieldMap)
continue;
if (!fieldMap) continue;

const fields = fieldMap.keys()
const fields = fieldMap.keys();
for (const field of fields) {
const fieldStat = fieldMap.get(field);

// Should never hit this since we check it is in the list of keys
if (!fieldStat)
continue;
if (!fieldStat) continue;

perFieldStat[field] = {
returnType: fieldStat.returnType,
requestsWithErrorsCount: fieldStat.requestsWithErrorsCount,
errorsCount: fieldStat.errorsCount,
latencyCount: fieldStat.latencyCount.toArray(),
count: fieldStat.count,
}
};
}
perTypeStat[type] = perFieldStat;
}
Expand Down
210 changes: 112 additions & 98 deletions packages/apollo-engine-reporting/src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import retry from 'async-retry';

import { plugin } from './plugin';
import {
GraphQLRequestContext, GraphQLRequestContextDidEncounterErrors,
GraphQLRequestContext,
GraphQLRequestContextDidEncounterErrors,
GraphQLRequestContextDidResolveOperation,
Logger
} from "apollo-server-types";
Logger,
} from 'apollo-server-types';
import { InMemoryLRUCache } from 'apollo-server-caching';
import { defaultEngineReportingSignature } from 'apollo-graphql';
import { ApolloServerPlugin } from 'apollo-server-plugin-base';
Expand Down Expand Up @@ -63,8 +64,8 @@ export type VariableValueOptions =
export type TraceReportingOptions<TContext> =
| ((
request:
| GraphQLRequestContextDidResolveOperation<TContext>
| GraphQLRequestContextDidEncounterErrors<TContext>,
| GraphQLRequestContextDidResolveOperation<TContext>
| GraphQLRequestContextDidEncounterErrors<TContext>,
) => Promise<boolean>)
| boolean;

Expand All @@ -73,10 +74,15 @@ export type GenerateClientInfo<TContext> = (
) => ClientInfo;

// AS3: Drop support for deprecated `ENGINE_API_KEY`.
export function getEngineApiKey(
{engine, skipWarn = false, logger= console }:
{engine: EngineReportingOptions<any> | boolean | undefined, skipWarn?: boolean, logger?: Logger }
) {
export function getEngineApiKey({
engine,
skipWarn = false,
logger = console,
}: {
engine: EngineReportingOptions<any> | boolean | undefined;
skipWarn?: boolean;
logger?: Logger;
}) {
if (typeof engine === 'object') {
if (engine.apiKey) {
return engine.apiKey;
Expand All @@ -85,34 +91,52 @@ export function getEngineApiKey(
const legacyApiKeyFromEnv = process.env.ENGINE_API_KEY;
const apiKeyFromEnv = process.env.APOLLO_KEY;

if(legacyApiKeyFromEnv && apiKeyFromEnv && !skipWarn) {
logger.warn("Using `APOLLO_KEY` since `ENGINE_API_KEY` (deprecated) is also set in the environment.");
if (legacyApiKeyFromEnv && apiKeyFromEnv && !skipWarn) {
logger.warn(
'Using `APOLLO_KEY` since `ENGINE_API_KEY` (deprecated) is also set in the environment.',
);
}
if(legacyApiKeyFromEnv && !warnedOnDeprecatedApiKey && !skipWarn) {
logger.warn("[deprecated] The `ENGINE_API_KEY` environment variable has been renamed to `APOLLO_KEY`.");
if (legacyApiKeyFromEnv && !warnedOnDeprecatedApiKey && !skipWarn) {
logger.warn(
'[deprecated] The `ENGINE_API_KEY` environment variable has been renamed to `APOLLO_KEY`.',
);
warnedOnDeprecatedApiKey = true;
}
return apiKeyFromEnv || legacyApiKeyFromEnv || ''
return apiKeyFromEnv || legacyApiKeyFromEnv || '';
}

// AS3: Drop support for deprecated `ENGINE_SCHEMA_TAG`.
export function getEngineGraphVariant(engine: EngineReportingOptions<any> | boolean | undefined, logger: Logger = console): string | undefined {
export function getEngineGraphVariant(
engine: EngineReportingOptions<any> | boolean | undefined,
logger: Logger = console,
): string | undefined {
if (engine === false) {
return;
} else if (typeof engine === 'object' && (engine.graphVariant || engine.schemaTag)) {
} else if (
typeof engine === 'object' &&
(engine.graphVariant || engine.schemaTag)
) {
if (engine.graphVariant && engine.schemaTag) {
throw new Error('Cannot set both engine.graphVariant and engine.schemaTag. Please use engine.graphVariant.');
throw new Error(
'Cannot set both engine.graphVariant and engine.schemaTag. Please use engine.graphVariant.',
);
}
if (engine.schemaTag) {
logger.warn('[deprecated] The `schemaTag` property within `engine` configuration has been renamed to `graphVariant`.');
logger.warn(
'[deprecated] The `schemaTag` property within `engine` configuration has been renamed to `graphVariant`.',
);
}
return engine.graphVariant || engine.schemaTag;
} else {
if (process.env.ENGINE_SCHEMA_TAG) {
logger.warn('[deprecated] The `ENGINE_SCHEMA_TAG` environment variable has been renamed to `APOLLO_GRAPH_VARIANT`.');
logger.warn(
'[deprecated] The `ENGINE_SCHEMA_TAG` environment variable has been renamed to `APOLLO_GRAPH_VARIANT`.',
);
}
if (process.env.ENGINE_SCHEMA_TAG && process.env.APOLLO_GRAPH_VARIANT) {
throw new Error('`APOLLO_GRAPH_VARIANT` and `ENGINE_SCHEMA_TAG` (deprecated) environment variables must not both be set.')
throw new Error(
'`APOLLO_GRAPH_VARIANT` and `ENGINE_SCHEMA_TAG` (deprecated) environment variables must not both be set.',
);
}
return process.env.APOLLO_GRAPH_VARIANT || process.env.ENGINE_SCHEMA_TAG;
}
Expand Down Expand Up @@ -364,7 +388,7 @@ export interface AddTraceArgs {
executableSchemaId: string;
source?: string;
document?: DocumentNode;
logger: Logger,
logger: Logger;
}

interface TraceCacheKey {
Expand Down Expand Up @@ -432,7 +456,11 @@ export class EngineReportingAgent<TContext = any> {

public constructor(options: EngineReportingOptions<TContext> = {}) {
this.options = options;
this.apiKey = getEngineApiKey({engine: this.options, skipWarn: false, logger: this.logger});
this.apiKey = getEngineApiKey({
engine: this.options,
skipWarn: false,
logger: this.logger,
});
if (options.logger) this.logger = options.logger;
this.bootId = uuidv4();
this.graphVariant = getEngineGraphVariant(options, this.logger) || '';
Expand All @@ -458,7 +486,7 @@ export class EngineReportingAgent<TContext = any> {

if (this.options.handleSignals !== false) {
const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM'];
signals.forEach((signal) => {
signals.forEach(signal => {
// Note: Node only started sending signal names to signal events with
// Node v10 so we can't use that feature here.
const handler: NodeJS.SignalsListener = async () => {
Expand Down Expand Up @@ -563,76 +591,66 @@ export class EngineReportingAgent<TContext = any> {
>();
}

const traceCacheKey = {
statsReportKey,
statsBucket: DurationHistogram.durationToBucket(trace.durationNs),
endsAtMinute:
((trace && trace.endTime && trace.endTime.seconds) || 0) % 60,
};

// If the buffer gets big (according to our estimate), send.
if (
this.sendReportsImmediately ||
reportData.size >=
(this.options.maxUncompressedReportSize || 4 * 1024 * 1024)
) {
await this.sendReportAndReportErrors(executableSchemaId);
const convertTraceToStats =
reportData.traceCache.get(traceCacheKey) === true;

const traceCacheKey = {
statsReportKey,
statsBucket: DurationHistogram.durationToBucket(trace.durationNs),
endsAtMinute:
((trace && trace.endTime && trace.endTime.seconds) || 0) % 60,
if (convertTraceToStats) {
const statsContext: IStatsContext = {
clientName: trace.clientName,
clientVersion: trace.clientVersion,
clientReferenceId: trace.clientReferenceId,
};

const convertTraceToStats =
reportData.traceCache.get(traceCacheKey) === true;
// TODO: Update sizing
let contextualizedStats: ContextualizedStats = (report.tracesPerQuery[
statsReportKey
] as any).statsMap.get(statsContext);

if (convertTraceToStats) {
const statsContext: IStatsContext = {
clientName: trace.clientName,
clientVersion: trace.clientVersion,
clientReferenceId: trace.clientReferenceId,
};

// TODO: Update sizing
let contextualizedStats: ContextualizedStats =
(report.tracesPerQuery[statsReportKey] as any).statsMap.get(
statsContext,
);

if (!contextualizedStats) {
contextualizedStats = new ContextualizedStats(statsContext);
(report.tracesPerQuery[statsReportKey] as any).statsMap.set(
statsContext,
contextualizedStats
);
}

contextualizedStats.addTrace(trace);
} else {
const protobufError = Trace.verify(trace);
if (protobufError) {
throw new Error(`Error encoding trace: ${protobufError}`);
}
const encodedTrace = Trace.encode(trace).finish();

// See comment on our override of Traces.encode inside of
// apollo-engine-reporting-protobuf to learn more about this strategy.
(report.tracesPerQuery[statsReportKey] as any).encodedTraces.push(
encodedTrace,
if (!contextualizedStats) {
contextualizedStats = new ContextualizedStats(statsContext);
(report.tracesPerQuery[statsReportKey] as any).statsMap.set(
statsContext,
contextualizedStats,
);
reportData.size += encodedTrace.length + Buffer.byteLength(statsReportKey);
}

// If the buffer gets big (according to our estimate), send.
if (
this.sendReportsImmediately ||
reportData.size >=
(this.options.maxUncompressedReportSize || 4 * 1024 * 1024)
) {
await this.sendReportAndReportErrors(executableSchemaId);
}
contextualizedStats.addTrace(trace);
} else {
const protobufError = Trace.verify(trace);
if (protobufError) {
throw new Error(`Error encoding trace: ${protobufError}`);
}
const encodedTrace = Trace.encode(trace).finish();

// See comment on our override of Traces.encode inside of
// apollo-engine-reporting-protobuf to learn more about this strategy.
(report.tracesPerQuery[statsReportKey] as any).encodedTraces.push(
encodedTrace,
);
reportData.size +=
encodedTrace.length + Buffer.byteLength(statsReportKey);
}

// If the buffer gets big (according to our estimate), send.
if (
this.sendReportsImmediately ||
reportData.size >=
(this.options.maxUncompressedReportSize || 4 * 1024 * 1024)
) {
await this.sendReportAndReportErrors(executableSchemaId);
}
}

public async sendAllReports(): Promise<void> {
await Promise.all(
Object.keys(this.reportDataByExecutableSchemaId).map((id) =>
Object.keys(this.reportDataByExecutableSchemaId).map(id =>
this.sendReport(id),
),
);
Expand Down Expand Up @@ -667,11 +685,12 @@ export class EngineReportingAgent<TContext = any> {

const statsKeys = Object.keys(report.tracesPerQuery);
for (const statsKey of statsKeys) {
const statsMap: Map<IStatsContext, ContextualizedStats> = (report.tracesPerQuery[statsKey] as any).statsMap;
const statsMap: Map<IStatsContext, ContextualizedStats> = (report
.tracesPerQuery[statsKey] as any).statsMap;
if (statsMap) {
let statsWithContext = report.tracesPerQuery[statsKey].statsWithContext
let statsWithContext = report.tracesPerQuery[statsKey].statsWithContext;
if (!statsWithContext) {
statsWithContext = new Array<ContextualizedStatsProto>()
statsWithContext = new Array<ContextualizedStatsProto>();
report.tracesPerQuery[statsKey].statsWithContext = statsWithContext;
}
for (const statWithContext of statsMap.values()) {
Expand Down Expand Up @@ -722,9 +741,8 @@ export class EngineReportingAgent<TContext = any> {

if (curResponse.status >= 500 && curResponse.status < 600) {
throw new Error(
`HTTP status ${curResponse.status}, ${
(await curResponse.text()) || '(no body)'
}`,
`HTTP status ${curResponse.status}, ${(await curResponse.text()) ||
'(no body)'}`,
);
} else {
return curResponse;
Expand Down Expand Up @@ -811,7 +829,7 @@ export class EngineReportingAgent<TContext = any> {
this.currentSchemaReporter = schemaReporter;
const logger = this.logger;

setTimeout(function () {
setTimeout(function() {
reportingLoop(schemaReporter, logger, false, fallbackReportingDelayInMs);
}, delay);
}
Expand Down Expand Up @@ -894,29 +912,25 @@ export class EngineReportingAgent<TContext = any> {
// either the request-specific logger on the request context (if available)
// or to the `logger` that was passed into `EngineReportingOptions` which
// is provided in the `EngineReportingAgent` constructor options.
this.signatureCache.set(cacheKey, generatedSignature)
.catch(err => {
logger.warn(
'Could not store signature cache. ' +
(err && err.message) || err
)
});
this.signatureCache.set(cacheKey, generatedSignature).catch(err => {
logger.warn(
'Could not store signature cache. ' + (err && err.message) || err,
);
});

return generatedSignature;
}

private async sendAllReportsAndReportErrors(): Promise<void> {
await Promise.all(
Object.keys(
this.reportDataByExecutableSchemaId,
).map((executableSchemaId) =>
Object.keys(this.reportDataByExecutableSchemaId).map(executableSchemaId =>
this.sendReportAndReportErrors(executableSchemaId),
),
);
}

private sendReportAndReportErrors(executableSchemaId: string): Promise<void> {
return this.sendReport(executableSchemaId).catch((err) => {
return this.sendReport(executableSchemaId).catch(err => {
// This catch block is primarily intended to catch network errors from
// the retried request itself, which include network errors and non-2xx
// HTTP errors.
Expand Down
5 changes: 2 additions & 3 deletions packages/apollo-engine-reporting/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ export const plugin = <TContext>(
| GraphQLRequestContextDidResolveOperation<TContext>
| GraphQLRequestContextDidEncounterErrors<TContext>,
): Promise<void> {
if (typeof options.traceReporting === "boolean") {
shouldReportTrace = options.traceReporting
if (typeof options.traceReporting === 'boolean') {
shouldReportTrace = options.traceReporting;
return;
}

Expand All @@ -153,7 +153,6 @@ export const plugin = <TContext>(
}
}


/**
* Due to a number of exceptions in the request pipeline — which are
* intended to preserve backwards compatible behavior with the
Expand Down

0 comments on commit 24b4141

Please sign in to comment.