diff --git a/packages/apollo-engine-reporting/src/agent.ts b/packages/apollo-engine-reporting/src/agent.ts index 580d36d6a19..1e3e6a48df1 100644 --- a/packages/apollo-engine-reporting/src/agent.ts +++ b/packages/apollo-engine-reporting/src/agent.ts @@ -79,6 +79,8 @@ export interface EngineReportingOptions { // 'sendReport()' on other signals if you'd like. Note that 'sendReport()' // does not run synchronously so it cannot work usefully in an 'exit' handler. handleSignals?: boolean; + // Sends the trace report immediately. This options is useful for stateless environments + sendReportsImmediately?: boolean; // XXX Provide a way to set client_name, client_version, client_address, // service, and service_version fields. They are currently not revealed in the @@ -103,6 +105,8 @@ export class EngineReportingAgent { private report!: FullTracesReport; private reportSize!: number; private reportTimer: any; // timer typing is weird and node-specific + private sendReportsImmediately?: boolean; + private stopped: boolean = false; public constructor(options: EngineReportingOptions = {}) { this.options = options; @@ -115,10 +119,13 @@ export class EngineReportingAgent { this.resetReport(); - this.reportTimer = setInterval( - () => this.sendReportAndReportErrors(), - this.options.reportIntervalMs || 10 * 1000, - ); + this.sendReportsImmediately = options.sendReportsImmediately; + if (!this.sendReportsImmediately) { + this.reportTimer = setInterval( + () => this.sendReportAndReportErrors(), + this.options.reportIntervalMs || 10 * 1000, + ); + } if (this.options.handleSignals !== false) { const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM']; @@ -141,7 +148,7 @@ export class EngineReportingAgent { public addTrace(signature: string, operationName: string, trace: Trace) { // Ignore traces that come in after stop(). - if (!this.reportTimer) { + if (this.stopped) { return; } @@ -165,8 +172,9 @@ export class EngineReportingAgent { // If the buffer gets big (according to our estimate), send. if ( + this.sendReportsImmediately || this.reportSize >= - (this.options.maxUncompressedReportSize || 4 * 1024 * 1024) + (this.options.maxUncompressedReportSize || 4 * 1024 * 1024) ) { this.sendReportAndReportErrors(); } @@ -270,6 +278,8 @@ export class EngineReportingAgent { clearInterval(this.reportTimer); this.reportTimer = undefined; } + + this.stopped = true; } private sendReportAndReportErrors(): Promise { diff --git a/packages/apollo-server-lambda/README.md b/packages/apollo-server-lambda/README.md index b748dec3b78..3e1c48ada9f 100644 --- a/packages/apollo-server-lambda/README.md +++ b/packages/apollo-server-lambda/README.md @@ -17,6 +17,8 @@ To deploy the AWS Lambda function we must create a Cloudformation Template and a #### 1. Write the API handlers +In a file named `graphql.js`, place the following code: + ```js const { ApolloServer, gql } = require('apollo-server-lambda'); @@ -136,7 +138,7 @@ exports.graphqlHandler = server.createHandler(); ## Modifying the Lambda Response (Enable CORS) -To enable CORS the response HTTP headers need to be modified. To accomplish this use `cors` options. +To enable CORS the response HTTP headers need to be modified. To accomplish this use the `cors` option. ```js const { ApolloServer, gql } = require('apollo-server-lambda'); diff --git a/packages/apollo-server-lambda/package.json b/packages/apollo-server-lambda/package.json index 207b4790083..852864a1370 100644 --- a/packages/apollo-server-lambda/package.json +++ b/packages/apollo-server-lambda/package.json @@ -32,6 +32,7 @@ "dependencies": { "@apollographql/graphql-playground-html": "^1.6.0", "apollo-server-core": "^2.0.0-rc.6", + "apollo-server-env": "^2.0.0-rc.6", "graphql-tools": "^3.0.4" }, "devDependencies": { diff --git a/packages/apollo-server-lambda/src/ApolloServer.ts b/packages/apollo-server-lambda/src/ApolloServer.ts index 2935707acc2..616452579b5 100644 --- a/packages/apollo-server-lambda/src/ApolloServer.ts +++ b/packages/apollo-server-lambda/src/ApolloServer.ts @@ -1,7 +1,7 @@ import * as lambda from 'aws-lambda'; import { ApolloServerBase } from 'apollo-server-core'; export { GraphQLOptions, GraphQLExtension } from 'apollo-server-core'; -import { GraphQLOptions } from 'apollo-server-core'; +import { GraphQLOptions, Config } from 'apollo-server-core'; import { renderPlaygroundPage, RenderPageOptions as PlaygroundRenderPageOptions, @@ -22,6 +22,19 @@ export interface CreateHandlerOptions { } export class ApolloServer extends ApolloServerBase { + // If you feel tempted to add an option to this constructor. Please consider + // another place, since the documentation becomes much more complicated when + // the constructor is not longer shared between all integration + constructor(options: Config) { + if (process.env.ENGINE_API_KEY || options.engine) { + options.engine = { + sendReportsImmediately: true, + ...(typeof options.engine !== 'boolean' ? options.engine : {}), + }; + } + super(options); + } + // This translates the arguments from the middleware into graphQL options It // provides typings for the integration specific behavior, ideally this would // be propagated with a generic to the super class diff --git a/packages/apollo-server-lambda/src/lambdaApollo.ts b/packages/apollo-server-lambda/src/lambdaApollo.ts index 1a80f0eba12..ebe1f6bb853 100644 --- a/packages/apollo-server-lambda/src/lambdaApollo.ts +++ b/packages/apollo-server-lambda/src/lambdaApollo.ts @@ -4,6 +4,7 @@ import { HttpQueryError, runHttpQuery, } from 'apollo-server-core'; +import { Headers } from 'apollo-server-env'; export interface LambdaGraphQLOptionsFunction { (event: lambda.APIGatewayProxyEvent, context: lambda.Context): @@ -45,7 +46,7 @@ export function graphqlLambda( request: { url: event.path, method: event.httpMethod, - headers: event.headers as any, + headers: new Headers(event.headers), }, }).then( ({ graphqlResponse, responseInit }) => {