@@ -3,13 +3,13 @@ import bodyParser from 'body-parser';
33import connect , { HandleFunction } from 'connect' ;
44import cookieParser from 'cookie-parser' ;
55import * as fs from 'fs-extra' ;
6- import { createServer , IncomingMessage , ServerResponse } from 'http' ;
6+ import { createServer , Server , IncomingMessage , ServerResponse } from 'http' ;
77import { StatusCodes } from 'http-status-codes' ;
88import * as os from 'os' ;
99import * as path from 'path' ;
1010import { URL } from 'url' ;
11- import { HttpError , InternalServerError } from './errors/http' ;
1211
12+ import { HttpError , InternalServerError } from './errors/http' ;
1313import { FunctionSet } from './function-set' ;
1414import { asyncMiddleware , cloudfrontPost } from './middlewares' ;
1515import { CloudFrontLifecycle , Origin , CacheService } from './services' ;
@@ -35,8 +35,10 @@ export class BehaviorRouter {
3535 private fileDir : string ;
3636 private path : string ;
3737
38+ private started : boolean = false ;
3839 private origins : Map < string , Origin > ;
39-
40+ private restarting : boolean = false ;
41+ private server : Server | null = null ;
4042 private cacheService : CacheService ;
4143 private log : ( message : string ) => void ;
4244
@@ -76,12 +78,56 @@ export class BehaviorRouter {
7678 return this . behaviors . get ( '*' ) || null ;
7779 }
7880
79- async listen ( port : number ) {
81+ async start ( port : number ) {
82+ this . started = true ;
83+
84+ return new Promise ( async ( res , rej ) => {
85+ await this . listen ( port ) ;
86+
87+ // While the server is in a "restarting state" just restart the server
88+ while ( this . restarting ) {
89+ this . restarting = false ;
90+ await this . listen ( port , false ) ;
91+ }
92+
93+ res ( 'Server shutting down ...' ) ;
94+ } ) ;
95+ }
96+
97+ public hasStarted ( ) {
98+ return this . started ;
99+ }
100+
101+ public isRunning ( ) {
102+ return this . server !== null ;
103+ }
104+
105+ public async restart ( ) {
106+ if ( this . restarting ) {
107+ return ;
108+ }
109+
110+ this . restarting = true ;
111+
112+ this . purgeBehaviourFunctions ( ) ;
113+ await this . shutdown ( ) ;
114+ }
115+
116+ private async shutdown ( ) {
117+ if ( this . server !== null ) {
118+ await this . server . close ( ) ;
119+ }
120+ this . server = null ;
121+ }
122+
123+ private async listen ( port : number , verbose : boolean = true ) {
80124 try {
81125 await this . extractBehaviors ( ) ;
82- this . logStorage ( ) ;
83- this . logBehaviors ( ) ;
84126
127+ if ( verbose ) {
128+ this . logStorage ( ) ;
129+ this . logBehaviors ( ) ;
130+ }
85131 const app = connect ( ) ;
86132
87133 app . use ( cloudfrontPost ( ) ) ;
@@ -133,10 +179,11 @@ export class BehaviorRouter {
133179
134180
135181 return new Promise ( resolve => {
136- const server = createServer ( app ) ;
137-
138- server . listen ( port ) ;
139- server . on ( 'close' , resolve ) ;
182+ this . server = createServer ( app ) ;
183+ this . server . listen ( port ) ;
184+ this . server . on ( 'close' , ( e : string ) => {
185+ resolve ( e ) ;
186+ } ) ;
140187 } ) ;
141188 } catch ( err ) {
142189 console . error ( err ) ;
@@ -200,6 +247,12 @@ export class BehaviorRouter {
200247 }
201248 }
202249
250+ private purgeBehaviourFunctions ( ) {
251+ this . behaviors . forEach ( ( behavior ) => {
252+ behavior . purgeLoadedFunctions ( ) ;
253+ } ) ;
254+ }
255+
203256 private logStorage ( ) {
204257 this . log ( `Cache directory: file://${ this . cacheDir } ` ) ;
205258 this . log ( `Files directory: file://${ this . fileDir } ` ) ;
0 commit comments