packageDocumentation module import { IModelHost , IpcHost } from "@itwin/core-backend" ; import { DisposeFunc , Logger } from "@itwin/core-bentley" ; import { RpcManager } from "@itwin/core-common" ; import { PresentationError , PresentationRpcInterface , PresentationStatus } from "@itwin/presentation-common" ; import { PresentationBackendLoggerCategory } from "./BackendLoggerCategory" ; import { PresentationIpcHandler } from "./PresentationIpcHandler" ; import { PresentationManager , PresentationManagerProps } from "./PresentationManager" ; import { PresentationRpcImpl } from "./PresentationRpcImpl" ; import { FactoryBasedTemporaryStorage } from "./TemporaryStorage" ; const defaultRequestTimeout = 90000 ; public export interface MultiManagerPresentationProps extends PresentationManagerProps { internal clientManagerFactory ? : ( clientId : string , props : PresentationManagerProps ) => PresentationManager ; /**
     * Time in milliseconds after which the request will timeout.
     */ requestTimeout ? : number ; /**
     * How much time should an unused client manager be stored in memory
     * before it's disposed.
     */ unusedClientLifetime ? : number ; } public export interface SingleManagerPresentationProps extends PresentationManagerProps { /**
     * How much time should an unused client manager be stored in memory
     * before it's disposed.
     */ requestTimeout ? : number ; alpha useSingleManager ? : boolean ; } public export type PresentationProps = MultiManagerPresentationProps | SingleManagerPresentationProps ; interface ClientStoreItem { manager : PresentationManager ; } public export class Presentation { private static _initProps : PresentationProps | undefined ; private static _clientsStorage : FactoryBasedTemporaryStorage < ClientStoreItem > | undefined ; private static _disposeIpcHandler : DisposeFunc | undefined ; private static _shutdownListener : DisposeFunc | undefined ; private static _manager : PresentationManager | undefined ; private static _rpcImpl : PresentationRpcImpl | undefined ; private constructor ( ) { } /** Properties used to initialize the presentation framework */ public static get initProps ( ) { return this . _initProps ; } param props public static initialize ( props ? ) { this . _initProps = props || { } ; this . _shutdownListener = IModelHost . onBeforeShutdown . addListener ( ( ) => Presentation . terminate ( ) ) ; this . _rpcImpl = new PresentationRpcImpl ( { requestTimeout : this . _initProps . requestTimeout ?? defaultRequestTimeout } ) ; RpcManager . registerImpl ( PresentationRpcInterface , PresentationRpcImpl ) ; RpcManager . supplyImplInstance ( PresentationRpcInterface , this . _rpcImpl ) ; if ( IpcHost . isValid ) { this . _disposeIpcHandler = PresentationIpcHandler . register ( ) ; } if ( isSingleManagerProps ( this . _initProps ) ) { this . _manager = new PresentationManager ( Presentation . _initProps ) ; } else { this . _clientsStorage = new FactoryBasedTemporaryStorage < ClientStoreItem > ( { factory : this . createClientManager . bind ( this ) , cleanupHandler : this . disposeClientManager , cleanupInterval : 60 * 1000 , unusedValueLifetime : this . _initProps . unusedClientLifetime ?? 60 * 60 * 1000 , onDisposedSingle : ( id ) => Logger . logInfo ( PresentationBackendLoggerCategory . PresentationManager , `Disposed PresentationManager instance with ID: ${ id }. Total instances: ${ this . _clientsStorage ! . values . length }.` ) , onDisposedAll : ( ) => Logger . logInfo ( PresentationBackendLoggerCategory . PresentationManager , `Disposed all PresentationManager instances.` ) } ) ; } } /**
     * Terminates Presentation. Consumers don't need to call this as it's automatically
     * called on [IModelHost.onBeforeShutdown]($core-backend) event.
     */ public static terminate ( ) { if ( this . _clientsStorage ) { this . _clientsStorage . dispose ( ) ; this . _clientsStorage = undefined ; } if ( this . _shutdownListener ) { this . _shutdownListener ( ) ; this . _shutdownListener = undefined ; } if ( this . _manager ) { this . _manager . dispose ( ) ; this . _manager = undefined ; } RpcManager . unregisterImpl ( PresentationRpcInterface ) ; if ( this . _rpcImpl ) { this . _rpcImpl . dispose ( ) ; this . _rpcImpl = undefined ; } if ( this . _disposeIpcHandler ) { this . _disposeIpcHandler ( ) ; } this . _initProps = undefined ; } private static createClientManager ( clientId , onManagerUsed ) { const manager = ( Presentation . _initProps && ! isSingleManagerProps ( Presentation . _initProps ) && Presentation . _initProps . clientManagerFactory ) ? Presentation . _initProps . clientManagerFactory ( clientId , Presentation . _initProps ) : new PresentationManager ( Presentation . _initProps ) ; manager . setOnManagerUsedHandler ( onManagerUsed ) ; Logger . logInfo ( PresentationBackendLoggerCategory . PresentationManager , `Created a PresentationManager instance with ID: ${ clientId }. Total instances: ${ this . _clientsStorage ! . values . length }.` ) ; return { manager } ; } private static disposeClientManager ( _id , storeItem ) { storeItem . manager . dispose ( ) ; } param clientId public static getManager ( clientId ? ) { if ( this . _initProps && isSingleManagerProps ( this . _initProps ) && this . _manager ) return this . _manager ; if ( this . _clientsStorage ) return this . _clientsStorage . getValue ( clientId || "" ) . manager ; throw new PresentationError ( PresentationStatus . NotInitialized , "Presentation must be first initialized by calling Presentation.initialize" ) ; } /**
     * Get the time in milliseconds that backend should respond in .
     */ public static getRequestTimeout ( ) { if ( this . _rpcImpl === undefined ) throw new PresentationError ( PresentationStatus . NotInitialized , "Presentation must be first initialized by calling Presentation.initialize" ) ; return this . _rpcImpl . requestTimeout ; } } function isSingleManagerProps ( props ) { return ! ! ( props as SingleManagerPresentationProps ) . useSingleManager ; }