mirror of
https://github.com/graphql-hive/console
synced 2026-04-21 14:37:17 +00:00
74 lines
2.8 KiB
TypeScript
74 lines
2.8 KiB
TypeScript
import { Injectable, Scope } from 'graphql-modules';
|
|
import type { ConditionalBreakingChangeMetadata, SchemaChangeType } from '@hive/storage';
|
|
import { formatNumber, formatPercentage } from '../lib/number-formatting';
|
|
|
|
/**
|
|
* A class to avoid type mapping and drilling types by storing the data in a WeakMap instead...
|
|
*/
|
|
@Injectable({
|
|
scope: Scope.Operation,
|
|
})
|
|
export class BreakingSchemaChangeUsageHelper {
|
|
constructor() {}
|
|
|
|
private breakingSchemaChangeToMetadataMap = new WeakMap<
|
|
SchemaChangeType,
|
|
ConditionalBreakingChangeMetadata
|
|
>();
|
|
|
|
registerMetadataForBreakingSchemaChange(
|
|
schemaChange: SchemaChangeType,
|
|
metadata: ConditionalBreakingChangeMetadata,
|
|
) {
|
|
this.breakingSchemaChangeToMetadataMap.set(schemaChange, metadata);
|
|
}
|
|
|
|
async getUsageDataForBreakingSchemaChange(schemaChange: SchemaChangeType) {
|
|
if (schemaChange.usageStatistics === null) {
|
|
return null;
|
|
}
|
|
|
|
const metadata = this.breakingSchemaChangeToMetadataMap.get(schemaChange);
|
|
|
|
if (metadata == null) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
topAffectedOperations: schemaChange.usageStatistics.topAffectedOperations.map(operation => {
|
|
// Note:
|
|
// "metadata.usage.totalRequestCount" is sometimes 0 in case of a integration test
|
|
// causing a zero devision and GraphQL exception,
|
|
// because we aggressively poll for the schema change after publishing usage data
|
|
// it seems like clickhouse slighty lags behind for the materialized view here.
|
|
// since it only happens in context of an integration test (no production issues)
|
|
// we can safely treat 0 as 1 request.
|
|
const totalRequestCount = Math.max(1, metadata.usage.totalRequestCount);
|
|
const percentage = (operation.count / totalRequestCount) * 100;
|
|
return {
|
|
...operation,
|
|
percentage,
|
|
targetIds: metadata.settings.targets.map(target => target.id),
|
|
};
|
|
}),
|
|
topAffectedClients: schemaChange.usageStatistics.topAffectedClients.map(client => {
|
|
// Note:
|
|
// "metadata.usage.totalRequestCount" is sometimes 0 in case of a integration test
|
|
// causing a zero devision and GraphQL exception,
|
|
// because we aggressively poll for the schema change after publishing usage data
|
|
// it seems like clickhouse slighty lags behind for the materialized view here.
|
|
// since it only happens in context of an integration test (no production issues)
|
|
// we can safely treat 0 as 1 request.
|
|
const totalRequestCount = Math.max(1, metadata.usage.totalRequestCount);
|
|
const percentage = (client.count / totalRequestCount) * 100;
|
|
|
|
return {
|
|
...client,
|
|
countFormatted: formatNumber(client.count),
|
|
percentage,
|
|
percentageFormatted: formatPercentage(percentage),
|
|
};
|
|
}),
|
|
};
|
|
}
|
|
}
|