16
16
17
17
// Functions framework entry point that configures and starts Node.js server
18
18
// that runs user's code on HTTP request.
19
- import { getUserFunction } from './loader' ;
20
- import { ErrorHandler } from './invoker' ;
21
- import { getServer } from './server' ;
22
- import { parseOptions , helpText , OptionsError } from './options' ;
23
- import { OpenFunction } from './functions' ;
19
+ import * as process from 'process' ;
20
+
21
+ import { createHttpTerminator } from 'http-terminator' ;
22
+
24
23
import getAysncServer from './openfunction/async_server' ;
25
24
import {
26
25
OpenFunctionContext ,
27
26
ContextUtils ,
28
27
} from './openfunction/function_context' ;
29
28
29
+ import { getUserFunction } from './loader' ;
30
+ import { ErrorHandler } from './invoker' ;
31
+ import { getServer } from './server' ;
32
+ import { parseOptions , helpText , OptionsError } from './options' ;
33
+ import { OpenFunction } from './functions' ;
34
+
30
35
/**
31
36
* Main entrypoint for the functions framework that loads the user's function
32
37
* and starts the HTTP server.
@@ -51,6 +56,8 @@ export const main = async () => {
51
56
}
52
57
const { userFunction, signatureType} = loadedFunction ;
53
58
59
+ // Try to determine the server runtime
60
+ // Considering the async runtime in the first place
54
61
if ( ContextUtils . IsAsyncRuntime ( options . context as OpenFunctionContext ) ) {
55
62
options . context ! . port = options . port ;
56
63
@@ -59,7 +66,12 @@ export const main = async () => {
59
66
options . context !
60
67
) ;
61
68
await server . start ( ) ;
62
- } else {
69
+
70
+ // DaprServer uses httpTerminator in server.stop()
71
+ handleShutdown ( async ( ) => await server . stop ( ) ) ;
72
+ }
73
+ // Then taking sync runtime as the fallback
74
+ else {
63
75
const server = getServer ( userFunction ! , signatureType , options . context ) ;
64
76
const errorHandler = new ErrorHandler ( server ) ;
65
77
server
@@ -73,6 +85,12 @@ export const main = async () => {
73
85
}
74
86
} )
75
87
. setTimeout ( 0 ) ; // Disable automatic timeout on incoming connections.
88
+
89
+ // Create and use httpTerminator for Express
90
+ const terminator = createHttpTerminator ( {
91
+ server,
92
+ } ) ;
93
+ handleShutdown ( async ( ) => await terminator . terminate ( ) ) ;
76
94
}
77
95
} catch ( e ) {
78
96
if ( e instanceof OptionsError ) {
@@ -86,3 +104,15 @@ export const main = async () => {
86
104
87
105
// Call the main method to load the user code and start the http server.
88
106
main ( ) ;
107
+
108
+ function handleShutdown ( handler : ( ) = > Promise < void > ) : void {
109
+ if ( ! handler ) return ;
110
+
111
+ const shutdown = async ( code : string ) => {
112
+ console . log ( `🛑 Terminating OpenFunction server on code ${ code } ...` ) ;
113
+ await handler ( ) ;
114
+ } ;
115
+
116
+ process . on ( 'SIGTERM' , shutdown ) ;
117
+ process . on ( 'SIGINT' , shutdown ) ;
118
+ }
0 commit comments