Skip to content

Commit

Permalink
fix: precompute schemahash (#301)
Browse files Browse the repository at this point in the history
* fix: precompute schemahash

* fix: apollo

* fix: apollo
  • Loading branch information
danstarns authored Apr 30, 2024
1 parent 1816d18 commit 4024553
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 59 deletions.
8 changes: 4 additions & 4 deletions benchmarks/apollo-debugger/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ if (cluster.isPrimary) {
} else {
const server = new ApolloServer({
typeDefs: `
type Query {
hello: String!
}
`,
type Query {
hello: String!
}
`,
resolvers: {
Query: {
hello: () => "world",
Expand Down
5 changes: 3 additions & 2 deletions benchmarks/helix-debugger/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ if (cluster.isPrimary) {
query,
variables,
request,
schema: tracedSchema,
schema: tracedSchema.schema,
contextFactory: () => ({
GraphQLDebuggerContext: new GraphQLDebuggerContext({
schema,
schema: tracedSchema.schema,
schemaHash: tracedSchema.schemaHash,
}),
}),
});
Expand Down
9 changes: 6 additions & 3 deletions docs/src/pages/docs/faq/missing-context.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ Inject the `GraphQLDebuggerContext` instance inside your GraphQL request context
```js
import { GraphQLDebuggerContext } from "@graphql-debugger/trace-schema";

const tracedScema = traceSchema({
schema,
adapter: // <-- See Adapters
});

const myServer = new GraphQLServerFooBar({
schema,
context: {
GraphQLDebuggerContext: new GraphQLDebuggerContext({
schema,
}),
GraphQLDebuggerContext: new GraphQLDebuggerContext(tracedSchema),
},
});
```
4 changes: 2 additions & 2 deletions docs/src/pages/docs/how.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ const tracedSchema = traceSchema({

// or
const tracedSchema = traceSchema({
schema,
adapter,
schema,
adapter,
});

```
Expand Down
11 changes: 4 additions & 7 deletions e2e/tests/utils/create-test-schema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { DebuggerClient } from "@graphql-debugger/client";
import { traceSchema } from "@graphql-debugger/trace-schema";
import { Schema } from "@graphql-debugger/types";
import { hashSchema } from "@graphql-debugger/utils";

import { faker } from "@faker-js/faker";
import { makeExecutableSchema } from "@graphql-tools/schema";
Expand Down Expand Up @@ -63,27 +62,25 @@ export async function createTestSchema({
resolvers,
});

const schema = traceSchema({
const { schema, schemaHash } = traceSchema({
schema: executableSchema,
adapter: client.adapter,
});

const hash = hashSchema(schema);

const dbSchema = await client.schema.upsert({
where: {
hash,
hash: schemaHash,
},
input: {
hash: hash,
hash: schemaHash,
typeDefs: typeDefs,
},
});

return {
schema,
typeDefs,
hash,
hash: schemaHash,
dbSchema,
query: /* GraphQL */ `
query ${shouldNameQuery ? random : ""} {
Expand Down
34 changes: 21 additions & 13 deletions packages/graphql-schema/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { traceSchema } from "@graphql-debugger/trace-schema";
import { hashSchema } from "@graphql-debugger/utils";

import SchemaBuilder from "@pothos/core";
import { GraphQLSchema } from "graphql";

import { TRACE_PRISMA, TRACE_SCHEMA } from "./config";
import { Context } from "./context";
Expand All @@ -23,17 +24,24 @@ require("./mutations");
const build = builder.toSchema();

export function createSchema({ client }: { client: DebuggerClient }) {
const schema = TRACE_SCHEMA
? traceSchema({
adapter: client.adapter,
schema: build,
...(TRACE_PRISMA && {
instrumentations: [tracing],
}),
})
: build;

const hash = hashSchema(schema);

return { schema, hash };
let schema: GraphQLSchema;
let schemaHash: string;

if (TRACE_SCHEMA) {
const tracedSchema = traceSchema({
schema: build,
adapter: client.adapter,
shouldExportSchema: false,
...(TRACE_PRISMA && {
instrumentations: [tracing],
}),
});
schema = tracedSchema.schema;
schemaHash = tracedSchema.schemaHash;
} else {
schema = build;
schemaHash = hashSchema(build);
}

return { schema, schemaHash };
}
3 changes: 2 additions & 1 deletion packages/trace-directive/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { GraphQLSchema } from "graphql";

export interface GraphQLDebuggerContextOptions {
schema: GraphQLSchema;
schemaHash?: string;
}

export class GraphQLDebuggerContext {
Expand All @@ -23,7 +24,7 @@ export class GraphQLDebuggerContext {

constructor(options: GraphQLDebuggerContextOptions) {
this.schema = options.schema;
this.schemaHash = hashSchema(options.schema);
this.schemaHash = options.schemaHash || hashSchema(options.schema);
this.tracer = getTracer();
}

Expand Down
8 changes: 6 additions & 2 deletions packages/trace-schema/src/trace-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { BaseAdapter } from "@graphql-debugger/adapter-base";
import { SetupOtelInput, setupOtel } from "@graphql-debugger/opentelemetry";
import { traceDirective } from "@graphql-debugger/trace-directive";
import { hashSchema } from "@graphql-debugger/utils";

import { makeExecutableSchema } from "@graphql-tools/schema";
import { getResolversFromSchema } from "@graphql-tools/utils";
Expand All @@ -27,7 +28,7 @@ export function traceSchema({
instrumentations,
shouldExportSchema = true,
shouldExcludeTypeFields = false,
}: TraceSchemaInput): GraphQLSchema {
}: TraceSchemaInput): { schema: GraphQLSchema; schemaHash: string } {
debug("Tracing schema");

setupOtel({ exporterConfig, instrumentations });
Expand Down Expand Up @@ -97,5 +98,8 @@ export function traceSchema({

debug("Traced schema");

return tracedSchema;
return {
schema: tracedSchema,
schemaHash: hashSchema(tracedSchema),
};
}
4 changes: 2 additions & 2 deletions packages/trace-schema/tests/trace-schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe("tracedSchema", () => {
shouldExportSchema: false,
});

const outputTypedefs = printSchemaWithDirectives(tracedSchema);
const outputTypedefs = printSchemaWithDirectives(tracedSchema.schema);

expect(outputTypedefs).toMatchInlineSnapshot(`
"schema {
Expand Down Expand Up @@ -99,7 +99,7 @@ type Query {
shouldExcludeTypeFields: true,
});

const outputTypedefs = printSchemaWithDirectives(tracedSchema);
const outputTypedefs = printSchemaWithDirectives(tracedSchema.schema);

expect(outputTypedefs).toMatchInlineSnapshot(`
"schema {
Expand Down
15 changes: 11 additions & 4 deletions plugins/apollo/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
GraphQLDebuggerContext,
SchemaExporer,
} from "@graphql-debugger/trace-schema";
import { hashSchema } from "@graphql-debugger/utils";

import { ApolloServerPlugin } from "@apollo/server";
import { Path } from "graphql/jsutils/Path";
Expand Down Expand Up @@ -48,6 +49,8 @@ export const graphqlDebuggerPlugin = ({
exporterConfig?: SetupOtelInput["exporterConfig"];
instrumentations?: SetupOtelInput["instrumentations"];
} = {}): ApolloServerPlugin<GraphQLContext> => {
let schemaHash: string;

return {
serverWillStart: async (service) => {
const schema = service.schema;
Expand All @@ -59,16 +62,20 @@ export const graphqlDebuggerPlugin = ({
schemaExporter.start();
}

schemaHash = hashSchema(schema);
setupOtel({ exporterConfig, instrumentations });
},
requestDidStart: async ({ schema }) => {
const spanMap = new Map<string, ApiSpan>();

return {
async executionDidStart() {
const internalCtx = new GraphQLDebuggerContext({
schema,
});
async executionDidStart(context) {
const internalCtx =
context.contextValue.GraphQLDebuggerContext ||
new GraphQLDebuggerContext({
schema,
schemaHash,
});

return {
willResolveField(fieldCtx) {
Expand Down
49 changes: 30 additions & 19 deletions plugins/yoga/src/create-yoga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,36 @@ export function createYoga<
throw new Error("Schema is required when using GraphQL Debugger");
}

let adapter = options?.debugger?.adapter;
if (!adapter) {
adapter = new ProxyAdapter();
}

let schema = options.schema;
let schemaHash = "";

if (options.debugger?.shouldDisable) {
schema = options.schema;
} else {
const tracedSchema = traceSchema({
schema,
adapter: adapter as BaseAdapter,
...options.debugger?.traceSchemaOptions,
});

schema = tracedSchema.schema;
schemaHash = tracedSchema.schemaHash;
}

const preComputedContext = {
schema,
schemaHash,
};

if (!options.context) {
const contextOverride = async (): Promise<TUserContext> => {
return {
GraphQLDebuggerContext: new GraphQLDebuggerContext({
schema: options.schema,
}),
GraphQLDebuggerContext: new GraphQLDebuggerContext(preComputedContext),
} as unknown as TUserContext;
};

Expand All @@ -55,27 +79,14 @@ export function createYoga<
options.context = async function newContextFunction(...args) {
const contextObject = await originalContextFunction(...args);

contextObject.GraphQLDebuggerContext = new GraphQLDebuggerContext({
schema: options.schema,
});
contextObject.GraphQLDebuggerContext = new GraphQLDebuggerContext(
preComputedContext,
);

return contextObject;
};
}

let adapter = options?.debugger?.adapter;
if (!adapter) {
adapter = new ProxyAdapter();
}

const schema = options.debugger?.shouldDisable
? options.schema
: traceSchema({
schema: options.schema,
adapter: adapter as BaseAdapter,
...options.debugger?.traceSchemaOptions,
});

const yoga = originalCreateYoga<TServerContext, TUserContext>({
...options,
schema,
Expand Down

0 comments on commit 4024553

Please sign in to comment.