diff --git a/controlplane/src/core/bufservices/analytics/getOperationContent.ts b/controlplane/src/core/bufservices/analytics/getOperationContent.ts index 4b76baab90..91536272a1 100644 --- a/controlplane/src/core/bufservices/analytics/getOperationContent.ts +++ b/controlplane/src/core/bufservices/analytics/getOperationContent.ts @@ -8,6 +8,8 @@ import { import type { RouterOptions } from '../../routes.js'; import { enrichLogger, getLogger, handleError } from '../../util.js'; +// Get operation content by hash +// TODO: Specify daterange to improve clickhouse performance export function getOperationContent( opts: RouterOptions, req: GetOperationContentRequest, @@ -47,6 +49,16 @@ export function getOperationContent( }; } + if (result.length === 0) { + return { + response: { + code: EnumStatusCode.ERR_NOT_FOUND, + details: 'Requested operation not found', + }, + operationContent: '', + }; + } + return { response: { code: EnumStatusCode.OK, diff --git a/controlplane/src/core/repositories/CacheWarmerRepository.ts b/controlplane/src/core/repositories/CacheWarmerRepository.ts index 323c475f60..61e03178cd 100644 --- a/controlplane/src/core/repositories/CacheWarmerRepository.ts +++ b/controlplane/src/core/repositories/CacheWarmerRepository.ts @@ -28,7 +28,7 @@ interface DBCacheWarmerOperation { content?: string; hash?: string; name?: string; - persistedID?: string; + persistedId?: string; clientName?: string; clientVersion?: string; planningTime?: number; @@ -49,6 +49,7 @@ export class CacheWarmerRepository { const parsedDateRange = isoDateRangeToTimestamps(dateRange, rangeInHours); const [start, end] = getDateRange(parsedDateRange); const quantile = 0.9; + const minPlanningTimeInMs = 0; const query = ` WITH @@ -58,8 +59,8 @@ export class CacheWarmerRepository { OperationHash as operationHash, OperationName as operationName, OperationPersistedID as operationPersistedID, - ClientName as clientName, - ClientVersion as clientVersion, + if(ClientName = 'unknown', '', ClientName) as clientName, + if(ClientVersion = 'missing', '', ClientVersion) as clientVersion, func_rank(${quantile}, BucketCounts) as rank, func_rank_bucket_lower_index(rank, BucketCounts) as b, round(func_histogram_v2( @@ -75,6 +76,7 @@ export class CacheWarmerRepository { AND OrganizationID = '${organizationId}' AND OperationName != 'IntrospectionQuery' GROUP BY OperationHash, OperationName, OperationPersistedID, ClientName, ClientVersion + HAVING planningTime > ${minPlanningTimeInMs} ORDER BY planningTime DESC LIMIT 100 `; @@ -235,7 +237,7 @@ export class CacheWarmerRepository { dbCacheWarmerOperations.push({ name: operation.operationName, hash: operation.operationHash, - persistedID: operation.operationPersistedID, + persistedId: operation.operationPersistedID, clientName: operation.clientName, clientVersion: operation.clientVersion, planningTime: operation.planningTime, @@ -253,7 +255,7 @@ export class CacheWarmerRepository { content: operationContent, name: operation.operationName, hash: operation.operationHash, - persistedID: operation.operationPersistedID, + persistedId: operation.operationPersistedID, clientName: operation.clientName, clientVersion: operation.clientVersion, planningTime: operation.planningTime, diff --git a/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go b/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go index 4b26186dde..107671e28f 100644 --- a/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go +++ b/graphqlmetrics/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go @@ -132,7 +132,7 @@ type SchemaUsageInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // RequestDocument is the GraphQL request document + // RequestDocument is the fully normalized GraphQL request document RequestDocument string `protobuf:"bytes,1,opt,name=RequestDocument,proto3" json:"RequestDocument,omitempty"` // TypeFieldMetrics is the list of used fields in the request document TypeFieldMetrics []*TypeFieldUsageInfo `protobuf:"bytes,2,rep,name=TypeFieldMetrics,proto3" json:"TypeFieldMetrics,omitempty"` diff --git a/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto b/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto index bff61b860c..29800621ac 100644 --- a/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto +++ b/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.proto @@ -17,7 +17,7 @@ message RequestInfo { } message SchemaUsageInfo { - // RequestDocument is the GraphQL request document + // RequestDocument is the fully normalized GraphQL request document string RequestDocument = 1; // TypeFieldMetrics is the list of used fields in the request document repeated TypeFieldUsageInfo TypeFieldMetrics = 2; diff --git a/router/core/graph_server.go b/router/core/graph_server.go index 54ffb1df4e..fa30d261c2 100644 --- a/router/core/graph_server.go +++ b/router/core/graph_server.go @@ -936,7 +936,8 @@ func (s *graphServer) buildGraphMux(ctx context.Context, err = WarmupCaches(ctx, warmupConfig) if err != nil { - return nil, fmt.Errorf("failed to warmup caches: %w", err) + // We don't want to fail the server if the cache warmup fails + s.logger.Error("Failed to warmup caches. It will retry after server restart or graph execution config update", zap.Error(err)) } } diff --git a/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go b/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go index f2d79181a3..7127c79946 100644 --- a/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go +++ b/router/gen/proto/wg/cosmo/graphqlmetrics/v1/graphqlmetrics.pb.go @@ -132,7 +132,7 @@ type SchemaUsageInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // RequestDocument is the GraphQL request document + // RequestDocument is the fully normalized GraphQL request document RequestDocument string `protobuf:"bytes,1,opt,name=RequestDocument,proto3" json:"RequestDocument,omitempty"` // TypeFieldMetrics is the list of used fields in the request document TypeFieldMetrics []*TypeFieldUsageInfo `protobuf:"bytes,2,rep,name=TypeFieldMetrics,proto3" json:"TypeFieldMetrics,omitempty"` diff --git a/studio/src/components/cache/cache-details-sheet.tsx b/studio/src/components/cache/cache-details-sheet.tsx index a1c47e3622..d0b1b371bf 100644 --- a/studio/src/components/cache/cache-details-sheet.tsx +++ b/studio/src/components/cache/cache-details-sheet.tsx @@ -247,7 +247,8 @@ export const CacheOperationDetails = ({ code={operationContent} language="graphql" disableLinking - className="scrollbar-custom w-3/6 overflow-auto" + prettyPrint={false} + className="scrollbar-custom overflow-auto" />