import { StartTransactionResult } from "aws-sdk/clients/qldbsession" ; import { Communicator } from "./Communicator" ; import { ExecuteError , isInvalidSessionException , isOccConflictException , isRetryableException , isTransactionExpiredException } from "./errors/Errors" ; import { warn } from "./LogUtil" ; import { Transaction } from "./Transaction" ; import { TransactionExecutor } from "./TransactionExecutor" ; internal export class QldbSession { private _communicator : Communicator ; private _isAlive : boolean ; constructor ( communicator ) { this . _communicator = communicator ; this . _isAlive = true ; } isAlive ( ) { return this . _isAlive ; } async endSession ( ) { try { this . _isAlive = false ; await this . _communicator . endSession ( ) ; } catch ( e ) { warn ( `Errors ending session: ${ e }.` ) ; } } async executeLambda < Type > ( transactionLambda ) { let transaction ; let transactionId = null ; let onCommit = false ; try { transaction = await this . _startTransaction ( ) ; transactionId = transaction . getTransactionId ( ) ; const executor = new TransactionExecutor ( transaction ) ; const returnedValue = await transactionLambda ( executor ) ; onCommit = true ; await transaction . commit ( ) ; return returnedValue ; } catch ( e ) { const isRetryable = isRetryableException ( e , onCommit ) ; const isISE = isInvalidSessionException ( e ) ; if ( isISE && ! isTransactionExpiredException ( e ) ) { this . _isAlive = false ; } else if ( ! isOccConflictException ( e ) ) { await this . _cleanSessionState ( ) ; } throw new ExecuteError ( e , isRetryable , isISE , transactionId ) ; } } async _startTransaction ( ) { const startTransactionResult = await this . _communicator . startTransaction ( ) ; return new Transaction ( this . _communicator , startTransactionResult . TransactionId ) ; } private async _cleanSessionState ( ) { try { await this . _communicator . abortTransaction ( ) ; } catch ( e ) { warn ( `Ignored error while aborting transaction during execution: ${ e }.` ) ; this . _isAlive = false ; } } }