/**
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * This module defines the top-level Runtime class which controls the
 * bootstrap's execution flow.
 */ "use strict" ; import BeforeExitListener from "./BeforeExitListener" ; import { HandlerFunction , IErrorCallbacks } from "../Common" ; import * as CallbackContext from "./CallbackContext" ; import InvokeContext from "./InvokeContext" ; import { IRuntimeClient } from "../RuntimeClient" ; export default class Runtime { client : IRuntimeClient ; errorCallbacks : IErrorCallbacks ; handler : HandlerFunction ; constructor ( client , handler , errorCallbacks ) { this . client = client ; this . handler = handler ; this . errorCallbacks = errorCallbacks ; } /**
     * Schedule the next loop iteration to start at the beginning of the next time
     * around the event loop.
     */ scheduleIteration ( ) { setImmediate ( ( ) => { this . handleOnce ( ) . then ( ( ) => { } , ( err ) => { console . log ( `Unexpected Top Level Error: ${ err . toString ( ) }` ) ; this . errorCallbacks . uncaughtException ( err ) ; } ) ; } ) ; } /**
     * Wait for the next invocation, process it, and schedule the next iteration.
     */ async handleOnce ( ) { const { bodyJson , headers } = await this . client . nextInvocation ( ) ; const invokeContext = new InvokeContext ( headers ) ; invokeContext . updateLoggingContext ( ) ; const [ callback , callbackContext ] = CallbackContext . build ( this . client , invokeContext . invokeId , this . scheduleIteration . bind ( this ) ) ; try { this . _setErrorCallbacks ( invokeContext . invokeId ) ; this . _setDefaultExitListener ( invokeContext . invokeId ) ; const result = this . handler ( JSON . parse ( bodyJson ) , invokeContext . attachEnvironmentData ( callbackContext ) , callback ) ; if ( _isPromise ( result ) ) { result . then ( callbackContext . succeed , callbackContext . fail ) . catch ( callbackContext . fail ) ; } } catch ( err ) { callback ( err ) ; } } param { String } invokeId private _setErrorCallbacks ( invokeId ) { this . errorCallbacks . uncaughtException = ( error ) : void => { this . client . postInvocationError ( error , invokeId , ( ) => { process . exit ( 129 ) ; } ) ; } ; this . errorCallbacks . unhandledRejection = ( error ) : void => { this . client . postInvocationError ( error , invokeId , ( ) => { process . exit ( 128 ) ; } ) ; } ; } /**
     * Setup the 'beforeExit' listener that is used if the callback is never
     * called and the handler is not async.
     * CallbackContext replaces the listener if a callback is invoked.
     */ private _setDefaultExitListener ( invokeId ) { BeforeExitListener . set ( ( ) => { this . client . postInvocationResponse ( null , invokeId , ( ) => this . scheduleIteration ( ) ) ; } ) ; } } function _isPromise ( obj ) { return obj instanceof Promise ; }