@@ -188,6 +188,16 @@ class EmberApp {
188188 }
189189 }
190190
191+ /**
192+ * Builds a new application instance sandbox as a micro-task.
193+ */
194+ buildNewApplicationInstance ( ) {
195+ return Promise . resolve ( ) . then ( ( ) => {
196+ let app = this . buildApp ( ) ;
197+ return app ;
198+ } ) ;
199+ }
200+
191201 /**
192202 * @private
193203 *
@@ -227,6 +237,29 @@ class EmberApp {
227237 return app ;
228238 }
229239
240+ /**
241+ * @private
242+ *
243+ * Get the new sandbox off if it is being created, otherwise create a new one on demand.
244+ * The later is needed when the current request hasn't finished or wasn't build with sandbox
245+ * per request turned on and a new request comes in.
246+ *
247+ */
248+ async _getNewApplicationInstance ( ) {
249+ let app ;
250+
251+ if ( this . _pendingNewApplicationInstance ) {
252+ let pendingAppInstancePromise = this . _pendingNewApplicationInstance ;
253+ this . _pendingNewApplicationInstance = undefined ;
254+ app = await pendingAppInstancePromise ;
255+ } else {
256+ // if there is no current pending application instance, create a new one on-demand.
257+ app = await this . buildApp ( ) ;
258+ }
259+
260+ return app ;
261+ }
262+
230263 /**
231264 * @private
232265 *
@@ -252,7 +285,7 @@ class EmberApp {
252285 async _visit ( path , fastbootInfo , bootOptions , result , buildSandboxPerVisit ) {
253286 let shouldBuildApp = buildSandboxPerVisit || this . _applicationInstance === undefined ;
254287
255- let app = shouldBuildApp ? await this . buildApp ( ) : this . _applicationInstance ;
288+ let app = shouldBuildApp ? await this . _getNewApplicationInstance ( ) : this . _applicationInstance ;
256289
257290 if ( buildSandboxPerVisit ) {
258291 // entangle the specific application instance to the result, so it can be
@@ -305,6 +338,7 @@ class EmberApp {
305338 let html = options . html || this . html ;
306339 let disableShoebox = options . disableShoebox || false ;
307340 let destroyAppInstanceInMs = parseInt ( options . destroyAppInstanceInMs , 10 ) ;
341+ let buildSandboxPerVisit = options . buildSandboxPerVisit || false ;
308342
309343 let shouldRender = options . shouldRender !== undefined ? options . shouldRender : true ;
310344 let bootOptions = buildBootOptions ( shouldRender ) ;
@@ -331,13 +365,7 @@ class EmberApp {
331365 }
332366
333367 try {
334- await this . _visit (
335- path ,
336- fastbootInfo ,
337- bootOptions ,
338- result ,
339- options . buildSandboxPerVisit === true
340- ) ;
368+ await this . _visit ( path , fastbootInfo , bootOptions , result , buildSandboxPerVisit ) ;
341369
342370 if ( ! disableShoebox ) {
343371 // if shoebox is not disabled, then create the shoebox and send API data
@@ -355,6 +383,12 @@ class EmberApp {
355383 result . _destroy ( ) ;
356384
357385 clearTimeout ( destroyAppInstanceTimer ) ;
386+
387+ if ( buildSandboxPerVisit ) {
388+ // if sandbox was built for this visit, then build a new sandbox for the next incoming request
389+ // which is invoked using buildSandboxPerVisit
390+ this . _pendingNewApplicationInstance = this . buildNewApplicationInstance ( ) ;
391+ }
358392 }
359393
360394 return result ;
0 commit comments