@@ -27,6 +27,7 @@ import {
27
27
import {
28
28
ApolloServerPlugin ,
29
29
GraphQLServiceContext ,
30
+ GraphQLServerListener ,
30
31
} from 'apollo-server-plugin-base' ;
31
32
import runtimeSupportsUploads from './utils/runtimeSupportsUploads' ;
32
33
@@ -72,13 +73,14 @@ import {
72
73
import { Headers } from 'apollo-server-env' ;
73
74
import { buildServiceDefinition } from '@apollographql/apollo-tools' ;
74
75
import { plugin as pluginTracing } from "apollo-tracing" ;
75
- import { Logger , SchemaHash } from "apollo-server-types" ;
76
+ import { Logger , SchemaHash , ValueOrPromise } from "apollo-server-types" ;
76
77
import {
77
78
plugin as pluginCacheControl ,
78
79
CacheControlExtensionOptions ,
79
80
} from 'apollo-cache-control' ;
80
81
import { getEngineApiKey , getEngineGraphVariant } from "apollo-engine-reporting/dist/agent" ;
81
82
import { cloneObject } from "./runHttpQuery" ;
83
+ import { Dispatcher } from './utils/dispatcher' ;
82
84
83
85
const NoIntrospection = ( context : ValidationContext ) => ( {
84
86
Field ( node : FieldDefinitionNode ) {
@@ -145,7 +147,7 @@ export class ApolloServerBase {
145
147
private config : Config ;
146
148
/** @deprecated : This is undefined for servers operating as gateways, and will be removed in a future release **/
147
149
protected schema ?: GraphQLSchema ;
148
- private toDispose = new Set < ( ) => void > ( ) ;
150
+ private toDispose = new Set < ( ) => ValueOrPromise < void > > ( ) ;
149
151
private experimental_approximateDocumentStoreMiB :
150
152
Config [ 'experimental_approximateDocumentStoreMiB' ] ;
151
153
@@ -173,6 +175,7 @@ export class ApolloServerBase {
173
175
gateway,
174
176
cacheControl,
175
177
experimental_approximateDocumentStoreMiB,
178
+ handleSignals,
176
179
...requestOptions
177
180
} = config ;
178
181
@@ -381,6 +384,26 @@ export class ApolloServerBase {
381
384
// is populated accordingly.
382
385
this . ensurePluginInstantiation ( plugins ) ;
383
386
387
+ if (
388
+ handleSignals !== false &&
389
+ // For backwards compatibility.
390
+ ( typeof this . config . engine !== 'object' ||
391
+ this . config . engine . handleSignals !== false )
392
+ ) {
393
+ const signals : NodeJS . Signals [ ] = [ 'SIGINT' , 'SIGTERM' ] ;
394
+ signals . forEach ( ( signal ) => {
395
+ // Note: Node only started sending signal names to signal events with
396
+ // Node v10 so we can't use that feature here.
397
+ const handler : NodeJS . SignalsListener = async ( ) => {
398
+ await this . stop ( ) ;
399
+ process . kill ( process . pid , signal ) ;
400
+ } ;
401
+ process . once ( signal , handler ) ;
402
+ this . toDispose . add ( ( ) => {
403
+ process . removeListener ( signal , handler ) ;
404
+ } ) ;
405
+ } ) ;
406
+ }
384
407
}
385
408
386
409
// used by integrations to synchronize the path with subscriptions, some
@@ -581,24 +604,33 @@ export class ApolloServerBase {
581
604
if ( this . requestOptions . persistedQueries ?. cache ) {
582
605
service . persistedQueries = {
583
606
cache : this . requestOptions . persistedQueries . cache ,
584
- }
607
+ } ;
585
608
}
586
609
587
- await Promise . all (
588
- this . plugins . map (
589
- plugin =>
590
- plugin . serverWillStart &&
591
- plugin . serverWillStart ( service ) ,
592
- ) ,
610
+ const serverListeners = (
611
+ await Promise . all (
612
+ this . plugins . map (
613
+ ( plugin ) => plugin . serverWillStart && plugin . serverWillStart ( service ) ,
614
+ ) ,
615
+ )
616
+ ) . filter (
617
+ ( maybeServerListener ) : maybeServerListener is GraphQLServerListener =>
618
+ typeof maybeServerListener === 'object' &&
619
+ ! ! maybeServerListener . serverWillStop ,
593
620
) ;
621
+ this . toDispose . add ( async ( ) => {
622
+ await Promise . all (
623
+ serverListeners . map ( ( { serverWillStop } ) => serverWillStop ?.( ) ) ,
624
+ ) ;
625
+ } ) ;
594
626
}
595
627
596
628
public async stop ( ) {
597
- this . toDispose . forEach ( dispose => dispose ( ) ) ;
629
+ await Promise . all ( [ ... this . toDispose ] . map ( dispose => dispose ( ) ) ) ;
598
630
if ( this . subscriptionServer ) await this . subscriptionServer . close ( ) ;
599
631
if ( this . engineReportingAgent ) {
600
632
this . engineReportingAgent . stop ( ) ;
601
- await this . engineReportingAgent . sendAllReports ( ) ;
633
+ await this . engineReportingAgent . sendAllReportsAndReportErrors ( ) ;
602
634
}
603
635
}
604
636
0 commit comments