From 174a2318fb998f08cc3a342fc8b76bfe994c3332 Mon Sep 17 00:00:00 2001 From: Kristina Koeva Date: Thu, 10 Nov 2016 16:01:51 +0200 Subject: [PATCH] Some refactorings. socket-proxy-factory is a Factory so move out the stop logic out of it. --- lib/declarations.ts | 1 - .../ios/socket-proxy-factory.ts | 38 ++++------ .../ios/socket-request-executor.ts | 3 +- lib/services/ios-debug-service.ts | 75 +++++++++---------- 4 files changed, 48 insertions(+), 69 deletions(-) diff --git a/lib/declarations.ts b/lib/declarations.ts index 490889fb56..1d80c93fba 100644 --- a/lib/declarations.ts +++ b/lib/declarations.ts @@ -234,7 +234,6 @@ interface IAndroidToolsInfoData { interface ISocketProxyFactory { createSocketProxy(factory: () => any): IFuture; - stopServer(): void; } interface IiOSNotification { diff --git a/lib/device-sockets/ios/socket-proxy-factory.ts b/lib/device-sockets/ios/socket-proxy-factory.ts index 0d5575ac8d..9e98fa51ee 100644 --- a/lib/device-sockets/ios/socket-proxy-factory.ts +++ b/lib/device-sockets/ios/socket-proxy-factory.ts @@ -10,12 +10,8 @@ export class SocketProxyFactory implements ISocketProxyFactory { private $config: IConfiguration, private $projectData: IProjectData, private $projectDataService: IProjectDataService, - private $processService: IProcessService, private $options: IOptions) { } - private _server: any; - private _sockets: net.Socket[] = []; - public createSocketProxy(factory: () => net.Socket): IFuture { return (() => { let socketFactory = (callback: (_socket: net.Socket) => void) => helpers.connectEventually(factory, callback); @@ -87,14 +83,11 @@ export class SocketProxyFactory implements ISocketProxyFactory { }); - this._server = server; - this.$processService.attachToProcessExitSignals(this, this.stopServer); - this.$logger.info("Opened localhost " + localPort); return server; } - private createTcpSocketProxy(socketFactory: (handler: (socket: net.Socket) => void) => void): string { + private createTcpSocketProxy(socketFactory: (handler: (socket: net.Socket) => void) => void): net.Server { this.$logger.info("\nSetting up proxy...\nPress Ctrl + C to terminate, or disconnect.\n"); let server = net.createServer({ @@ -104,8 +97,6 @@ export class SocketProxyFactory implements ISocketProxyFactory { server.on("connection", (frontendSocket: net.Socket) => { this.$logger.info("Frontend client connected."); - this._sockets.push(frontendSocket); - frontendSocket.on("end", () => { this.$logger.info('Frontend socket closed!'); if (!(this.$config.debugLivesync && this.$options.watch)) { @@ -123,6 +114,17 @@ export class SocketProxyFactory implements ISocketProxyFactory { } }); + frontendSocket.on("close", () => { + if (!(backendSocket).destroyed) { + backendSocket.destroy(); + } + }); + backendSocket.on("close", () => { + if (!(frontendSocket).destroyed) { + frontendSocket.destroy(); + } + }); + backendSocket.pipe(frontendSocket); frontendSocket.pipe(backendSocket); frontendSocket.resume(); @@ -135,21 +137,7 @@ export class SocketProxyFactory implements ISocketProxyFactory { this.$logger.info("socket-file-location: " + socketFileLocation); } - this._server = server; - this.$processService.attachToProcessExitSignals(this, this.stopServer); - - return socketFileLocation; - } - - public stopServer() { - if (this._server) { - this._server.close(); - for (let socket of this._sockets) { - socket.destroy(); - } - this._sockets = []; - this._server = null; - } + return server; } } $injector.register("socketProxyFactory", SocketProxyFactory); diff --git a/lib/device-sockets/ios/socket-request-executor.ts b/lib/device-sockets/ios/socket-request-executor.ts index 1aa75ce8b5..dd46f7090b 100644 --- a/lib/device-sockets/ios/socket-request-executor.ts +++ b/lib/device-sockets/ios/socket-request-executor.ts @@ -7,8 +7,7 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { private $iOSNotification: IiOSNotification, private $iOSNotificationService: IiOSNotificationService, private $logger: ILogger, - private $projectData: IProjectData, - private $socketProxyFactory: ISocketProxyFactory) { } + private $projectData: IProjectData) { } public executeAttachRequest(device: Mobile.IiOSDevice, timeout: number): IFuture { return (() => { diff --git a/lib/services/ios-debug-service.ts b/lib/services/ios-debug-service.ts index 118d6379a5..addde79051 100644 --- a/lib/services/ios-debug-service.ts +++ b/lib/services/ios-debug-service.ts @@ -8,9 +8,14 @@ const inspectorBackendPort = 18181; const inspectorAppName = "NativeScript Inspector.app"; const inspectorNpmPackageName = "tns-ios-inspector"; const inspectorUiDir = "WebInspectorUI/"; -const TIMEOUT_SECONDS = 90; +const TIMEOUT_SECONDS = 9; class IOSDebugService implements IDebugService { + private _lldbProcess: ChildProcess; + private _sockets: net.Socket[] = []; + private _childProcess: ChildProcess; + private _socketProxy: net.Server; + constructor( private $config: IConfiguration, private $platformService: IPlatformService, @@ -35,10 +40,6 @@ class IOSDebugService implements IDebugService { this.$processService.attachToProcessExitSignals(this, this.debugStop); } - private _lldbProcess: ChildProcess; - private _sockets: net.Socket[] = []; - private _childProcess: ChildProcess; - public get platform(): string { return "ios"; } @@ -80,16 +81,20 @@ class IOSDebugService implements IDebugService { public debugStop(): IFuture { return (() => { - this.$socketProxyFactory.stopServer(); - for (let socket of this._sockets) { - socket.destroy(); + if (this._socketProxy) { + this._socketProxy.close(); + this._socketProxy = null; } + + _.forEach(this._sockets, socket => socket.destroy()); this._sockets = []; + if (this._lldbProcess) { this._lldbProcess.stdin.write("process detach\n"); this._lldbProcess.kill(); this._lldbProcess = undefined; } + if (this._childProcess) { this._childProcess.kill(); this._childProcess = undefined; @@ -163,9 +168,7 @@ class IOSDebugService implements IDebugService { private debugBrkCore(device: Mobile.IiOSDevice, shouldBreak?: boolean): IFuture { return (() => { let timeout = this.$utils.getMilliSecondsTimeout(TIMEOUT_SECONDS); - let readyForAttachTimeout = this.getReadyForAttachTimeout(timeout); - - this.$iOSSocketRequestExecutor.executeLaunchRequest(device, timeout, readyForAttachTimeout, shouldBreak).wait(); + this.$iOSSocketRequestExecutor.executeLaunchRequest(device, timeout, timeout, shouldBreak).wait(); this.wireDebuggerClient(device).wait(); }).future()(); } @@ -179,7 +182,7 @@ class IOSDebugService implements IDebugService { private deviceStartCore(device: Mobile.IiOSDevice): IFuture { return (() => { - let timeout = this.getReadyForAttachTimeout(); + let timeout = this.$utils.getMilliSecondsTimeout(TIMEOUT_SECONDS); this.$iOSSocketRequestExecutor.executeAttachRequest(device, timeout).wait(); this.wireDebuggerClient(device).wait(); }).future()(); @@ -187,48 +190,38 @@ class IOSDebugService implements IDebugService { private wireDebuggerClient(device?: Mobile.IiOSDevice): IFuture { return (() => { - let socketProxy = this.$socketProxyFactory.createSocketProxy(() => { + this._socketProxy = this.$socketProxyFactory.createSocketProxy(() => { let socket = device ? device.connectToPort(inspectorBackendPort) : net.connect(inspectorBackendPort); this._sockets.push(socket); return socket; }).wait(); - this.executeOpenDebuggerClient(socketProxy).wait(); + + this.openDebuggerClient(this._socketProxy.address()).wait(); }).future()(); } - public executeOpenDebuggerClient(fileDescriptor: string): IFuture { + private openDebuggerClient(fileDescriptor: string): IFuture { if (this.$options.client) { - return this.openDebuggingClient(fileDescriptor); + return (() => { + let inspectorPath = this.$npmInstallationManager.install(inspectorNpmPackageName).wait(); + let inspectorSourceLocation = path.join(inspectorPath, inspectorUiDir, "Main.html"); + let inspectorApplicationPath = path.join(inspectorPath, inspectorAppName); + + // TODO : Sadly $npmInstallationManager.install does not install the package, it only inserts it in the cache through the npm cache add command + // Since npm cache add command does not execute scripts our posinstall script that extract the Inspector Application does not execute as well + // So until this behavior is changed this ugly workaround should not be deleted + if (!this.$fs.exists(inspectorApplicationPath).wait()) { + this.$npm.executeNpmCommand("npm run-script postinstall", inspectorPath).wait(); + } + + let cmd = `open -a '${inspectorApplicationPath}' --args '${inspectorSourceLocation}' '${this.$projectData.projectName}' '${fileDescriptor}'`; + this.$childProcess.exec(cmd).wait(); + }).future()(); } else { return (() => { this.$logger.info("Suppressing debugging client."); }).future()(); } } - - private openDebuggingClient(fileDescriptor: string): IFuture { - return (() => { - let inspectorPath = this.$npmInstallationManager.install(inspectorNpmPackageName).wait(); - let inspectorSourceLocation = path.join(inspectorPath, inspectorUiDir, "Main.html"); - let inspectorApplicationPath = path.join(inspectorPath, inspectorAppName); - - // TODO : Sadly $npmInstallationManager.install does not install the package, it only inserts it in the cache through the npm cache add command - // Since npm cache add command does not execute scripts our posinstall script that extract the Inspector Application does not execute as well - // So until this behavior is changed this ugly workaround should not be deleted - if (!this.$fs.exists(inspectorApplicationPath).wait()) { - this.$npm.executeNpmCommand("npm run-script postinstall", inspectorPath).wait(); - } - - let cmd = `open -a '${inspectorApplicationPath}' --args '${inspectorSourceLocation}' '${this.$projectData.projectName}' '${fileDescriptor}'`; - this.$childProcess.exec(cmd).wait(); - }).future()(); - } - - private getReadyForAttachTimeout(timeoutInMilliseconds?: number): number { - let timeout = timeoutInMilliseconds || this.$utils.getMilliSecondsTimeout(TIMEOUT_SECONDS); - let readyForAttachTimeout = timeout / 10; - let defaultReadyForAttachTimeout = 5000; - return readyForAttachTimeout > defaultReadyForAttachTimeout ? readyForAttachTimeout : defaultReadyForAttachTimeout; - } } $injector.register("iOSDebugService", IOSDebugService);