1616
1717// Functions framework entry point that configures and starts Node.js server
1818// 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+
2423import getAysncServer from './openfunction/async_server' ;
2524import {
2625 OpenFunctionContext ,
2726 ContextUtils ,
2827} from './openfunction/function_context' ;
2928
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+
3035/**
3136 * Main entrypoint for the functions framework that loads the user's function
3237 * and starts the HTTP server.
@@ -51,6 +56,8 @@ export const main = async () => {
5156 }
5257 const { userFunction, signatureType} = loadedFunction ;
5358
59+ // Try to determine the server runtime
60+ // Considering the async runtime in the first place
5461 if ( ContextUtils . IsAsyncRuntime ( options . context as OpenFunctionContext ) ) {
5562 options . context ! . port = options . port ;
5663
@@ -59,7 +66,12 @@ export const main = async () => {
5966 options . context !
6067 ) ;
6168 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 {
6375 const server = getServer ( userFunction ! , signatureType , options . context ) ;
6476 const errorHandler = new ErrorHandler ( server ) ;
6577 server
@@ -73,6 +85,12 @@ export const main = async () => {
7385 }
7486 } )
7587 . 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 ( ) ) ;
7694 }
7795 } catch ( e ) {
7896 if ( e instanceof OptionsError ) {
@@ -86,3 +104,15 @@ export const main = async () => {
86104
87105// Call the main method to load the user code and start the http server.
88106main ( ) ;
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