Skip to content

Commit 2a7049d

Browse files
Mitko-Kerezovrosen-vladimirov
authored andcommitted
Fix livesync for ios devices
Currently we are creating new instance of the AndroidLiveSyncService and IOSLiveSyncService. When `--watch` option is used, CLI gets new instance for each change of a file. This leads to opening new socket every single time. The second changed file leads to process exit as the inspector runtime logic is triggered many times. Fix this by caching the instances per device.
1 parent 7553ab5 commit 2a7049d

File tree

2 files changed

+59
-13
lines changed

2 files changed

+59
-13
lines changed

lib/providers/livesync-provider.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,22 @@ export class LiveSyncProvider implements ILiveSyncProvider {
1212

1313
private static FAST_SYNC_FILE_EXTENSIONS = [".css", ".xml"];
1414

15+
private platformSpecificLiveSyncServicesCache: IDictionary<any> = {};
1516
public get platformSpecificLiveSyncServices(): IDictionary<any> {
1617
return {
1718
android: (_device: Mobile.IDevice, $injector: IInjector): IPlatformLiveSyncService => {
18-
return $injector.resolve(this.$androidLiveSyncServiceLocator.factory, {_device: _device});
19+
if(!this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier]) {
20+
this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier] = $injector.resolve(this.$androidLiveSyncServiceLocator.factory, {_device: _device});
21+
}
22+
23+
return this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier];
1924
},
2025
ios: (_device: Mobile.IDevice, $injector: IInjector) => {
21-
return $injector.resolve(this.$iosLiveSyncServiceLocator.factory, {_device: _device});
26+
if(!this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier]) {
27+
this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier] = $injector.resolve(this.$iosLiveSyncServiceLocator.factory, {_device: _device});
28+
}
29+
30+
return this.platformSpecificLiveSyncServicesCache[_device.deviceInfo.identifier];
2231
}
2332
};
2433
}

lib/services/livesync/ios-livesync-service.ts

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ let currentPageReloadId = 0;
99

1010
class IOSLiveSyncService extends liveSyncServiceBaseLib.LiveSyncServiceBase<Mobile.IiOSDevice> implements IPlatformLiveSyncService {
1111
private static BACKEND_PORT = 18181;
12+
private socket: net.Socket;
1213

1314
constructor(_device: Mobile.IDevice,
1415
private $iOSSocketRequestExecutor: IiOSSocketRequestExecutor,
1516
private $iOSNotification: IiOSNotification,
1617
private $iOSEmulatorServices: Mobile.IiOSSimulatorService,
1718
private $injector: IInjector,
18-
private $logger: ILogger) {
19+
private $logger: ILogger,
20+
private $options: IOptions) {
1921
super(_device);
2022
}
2123

@@ -34,36 +36,71 @@ class IOSLiveSyncService extends liveSyncServiceBaseLib.LiveSyncServiceBase<Mobi
3436
return (() => {
3537
let timeout = 9000;
3638
if (this.device.isEmulator) {
37-
helpers.connectEventually(() => net.connect(IOSLiveSyncService.BACKEND_PORT), (socket: net.Socket) => this.sendPageReloadMessage(socket));
39+
if (!this.socket) {
40+
helpers.connectEventually(() => net.connect(IOSLiveSyncService.BACKEND_PORT), (socket: net.Socket) => {
41+
this.socket = socket;
42+
if(this.$options.watch) {
43+
this.attachProcessExitHandlers();
44+
}
45+
this.sendPageReloadMessage();
46+
});
47+
} else {
48+
this.sendPageReloadMessage();
49+
}
3850
this.$iOSEmulatorServices.postDarwinNotification(this.$iOSNotification.attachRequest).wait();
3951
} else {
4052
this.$iOSSocketRequestExecutor.executeAttachRequest(this.device, timeout).wait();
41-
let socket = this.device.connectToPort(IOSLiveSyncService.BACKEND_PORT);
42-
this.sendPageReloadMessage(socket);
53+
this.socket = this.device.connectToPort(IOSLiveSyncService.BACKEND_PORT);
54+
this.sendPageReloadMessage();
4355
}
4456
}).future<void>()();
4557
}
4658

47-
private sendPageReloadMessage(socket: net.Socket): void {
59+
private sendPageReloadMessage(): void {
4860
try {
49-
this.sendPageReloadMessageCore(socket);
50-
socket.once("data", (data: NodeBuffer|string) => {
61+
this.sendPageReloadMessageCore();
62+
this.socket.on("data", (data: NodeBuffer|string) => {
5163
this.$logger.trace(`Socket sent data: ${data.toString()}`);
52-
socket.destroy();
64+
this.destroySocketIfNecessary();
5365
});
5466
} catch(err) {
5567
this.$logger.trace("Error while sending page reload:", err);
56-
socket.destroy();
68+
this.destroySocketIfNecessary();
5769
}
5870
}
5971

60-
private sendPageReloadMessageCore(socket: net.Socket): void {
72+
private sendPageReloadMessageCore(): void {
6173
let message = `{ "method":"Page.reload","params":{"ignoreCache":false},"id":${++currentPageReloadId} }`;
6274
let length = Buffer.byteLength(message, "utf16le");
6375
let payload = new Buffer(length + 4);
6476
payload.writeInt32BE(length, 0);
6577
payload.write(message, 4, length, "utf16le");
66-
socket.write(payload);
78+
this.socket.write(payload);
79+
}
80+
81+
private attachProcessExitHandlers(): void {
82+
process.on("exit", (exitCode: number) => {
83+
this.destroySocket();
84+
});
85+
86+
process.on("SIGTERM", () => {
87+
this.destroySocket();
88+
});
89+
90+
process.on("SIGINT", () => {
91+
this.destroySocket();
92+
});
93+
}
94+
95+
private destroySocketIfNecessary(): void {
96+
if(!this.$options.watch) {
97+
this.destroySocket();
98+
}
99+
}
100+
101+
private destroySocket(): void {
102+
this.socket.destroy();
103+
this.socket = null;
67104
}
68105
}
69106
$injector.register("iosLiveSyncServiceLocator", {factory: IOSLiveSyncService});

0 commit comments

Comments
 (0)