Skip to content

Commit b74d362

Browse files
fix: do not start emulator detection interval
The emulator detection interval is not required for CLI and in fact it just uses CPU and memory. Also, it causes some issues when you do not hava JAVA installed. So remove start of emulator detection interval and allow it to be started from the API, when CLI is used as a library.
1 parent 4971447 commit b74d362

File tree

7 files changed

+143
-88
lines changed

7 files changed

+143
-88
lines changed

lib/common/bootstrap.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ $injector.require("errors", "./errors");
66
$injector.requirePublic("fs", "./file-system");
77
$injector.require("hostInfo", "./host-info");
88
$injector.require("osInfo", "./os-info");
9+
$injector.require("timers", "./timers");
910

1011
$injector.require("dispatcher", "./dispatchers");
1112
$injector.require("commandDispatcher", "./dispatchers");

lib/common/definitions/mobile.d.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -387,11 +387,7 @@ declare module Mobile {
387387
/**
388388
* Describes options that can be passed to devices service's initialization method.
389389
*/
390-
interface IDevicesServicesInitializationOptions {
391-
/**
392-
* The platform for which to initialize. If passed will detect only devices belonging to said platform.
393-
*/
394-
platform?: string;
390+
interface IDevicesServicesInitializationOptions extends Partial<IDeviceLookingOptions> {
395391
/**
396392
* If passed will start an emulator if necesasry.
397393
*/
@@ -412,10 +408,6 @@ declare module Mobile {
412408
* Specifies whether we should skip the emulator starting.
413409
*/
414410
skipEmulatorStart?: boolean;
415-
/**
416-
* Defines if the initialization should await the whole iOS detection to finish or it can just start the detection.
417-
*/
418-
shouldReturnImmediateResult?: boolean;
419411
/**
420412
* Currently available only for iOS. Specifies the sdk version of the iOS simulator.
421413
* In case when `tns run ios --device "iPhone 6"` command is executed, the user can specify the sdk of the simulator because it is possible to have more than one device with the same name but with different sdk versions.
@@ -1029,7 +1021,11 @@ declare module Mobile {
10291021
resolveProductName(deviceType: string): string;
10301022
}
10311023

1032-
interface IDeviceLookingOptions extends IHasEmulatorOption {
1024+
interface IHasDetectionInterval {
1025+
detectionInterval?: number;
1026+
}
1027+
1028+
interface IDeviceLookingOptions extends IHasEmulatorOption, IHasDetectionInterval {
10331029
shouldReturnImmediateResult: boolean;
10341030
platform: string;
10351031
}

lib/common/definitions/timers.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
interface ITimers {
2+
setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
3+
}

lib/common/mobile/mobile-core/devices-service.ts

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { CONNECTED_STATUS } from "../../constants";
1010
import { isInteractive } from "../../helpers";
1111
import { DebugCommandErrors } from "../../../constants";
1212
import { performanceLog } from "../../decorators";
13+
import { Timers } from "../../timers";
1314

1415
export class DevicesService extends EventEmitter implements Mobile.IDevicesService {
1516
private static DEVICE_LOOKING_INTERVAL = 200;
@@ -22,7 +23,8 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi
2223
private _data: Mobile.IDevicesServicesInitializationOptions;
2324
private _otherDeviceDiscoveries: Mobile.IDeviceDiscovery[] = [];
2425
private _allDeviceDiscoveries: Mobile.IDeviceDiscovery[] = [];
25-
private deviceDetectionIntervals: NodeJS.Timer[] = [];
26+
private deviceDetectionInterval: NodeJS.Timer;
27+
private emulatorDetectionInterval: NodeJS.Timer;
2628

2729
constructor(private $logger: ILogger,
2830
private $errors: IErrors,
@@ -37,12 +39,12 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi
3739
private $injector: IInjector,
3840
private $options: IOptions,
3941
private $androidProcessService: Mobile.IAndroidProcessService,
40-
private $processService: IProcessService,
4142
private $iOSEmulatorServices: Mobile.IiOSSimulatorService,
4243
private $androidEmulatorServices: Mobile.IEmulatorPlatformService,
4344
private $androidEmulatorDiscovery: Mobile.IDeviceDiscovery,
4445
private $emulatorHelper: Mobile.IEmulatorHelper,
45-
private $prompter: IPrompter) {
46+
private $prompter: IPrompter,
47+
private $timers: Timers) {
4648
super();
4749
this.attachToKnownDeviceDiscoveryEvents();
4850
this.attachToKnownEmulatorDiscoveryEvents();
@@ -261,7 +263,7 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi
261263
/**
262264
* Starts looking for devices. Any found devices are pushed to "_devices" variable.
263265
*/
264-
protected async detectCurrentlyAttachedDevices(deviceInitOpts?: Mobile.IDevicesServicesInitializationOptions): Promise<void> {
266+
protected async detectCurrentlyAttachedDevices(deviceInitOpts?: Mobile.IDeviceLookingOptions): Promise<void> {
265267
const options = this.getDeviceLookingOptions(deviceInitOpts);
266268

267269
for (const deviceDiscovery of this._allDeviceDiscoveries) {
@@ -277,7 +279,7 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi
277279
try {
278280
await this.$androidEmulatorDiscovery.startLookingForDevices();
279281
} catch (err) {
280-
this.$logger.trace(`Error while checking for android emulators. ${err}`);
282+
this.$logger.trace(`Error while checking for Android emulators. ${err}`);
281283
}
282284

283285
try {
@@ -287,51 +289,63 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi
287289
}
288290
}
289291

290-
protected async startDeviceDetectionIntervals(deviceInitOpts: Mobile.IDevicesServicesInitializationOptions = {}): Promise<void> {
291-
this.$processService.attachToProcessExitSignals(this, this.clearDeviceDetectionInterval);
292-
293-
if (this.deviceDetectionIntervals.length) {
294-
this.$logger.trace("Device detection intervals are already started. New intervals will not be started.");
295-
return;
296-
}
292+
@exported("devicesService")
293+
public startDeviceDetectionInterval(deviceInitOpts: Mobile.IDeviceLookingOptions = <any>{}): void {
294+
if (!this.deviceDetectionInterval) {
295+
let isDeviceDetectionIntervalInProgress = false;
297296

298-
let isDeviceDetectionIntervalInProgress = false;
299-
const deviceDetectionInterval = setInterval(async () => {
300-
if (isDeviceDetectionIntervalInProgress) {
301-
return;
302-
}
297+
this.deviceDetectionInterval = this.$timers.setInterval(async () => {
298+
if (isDeviceDetectionIntervalInProgress) {
299+
return;
300+
}
303301

304-
isDeviceDetectionIntervalInProgress = true;
302+
isDeviceDetectionIntervalInProgress = true;
305303

306-
await this.detectCurrentlyAttachedDevices(deviceInitOpts);
304+
await this.detectCurrentlyAttachedDevices(deviceInitOpts);
307305

308-
try {
309-
const trustedDevices = _.filter(this._devices, device => device.deviceInfo.status === constants.CONNECTED_STATUS);
310-
await settlePromises(_.map(trustedDevices, device => device.applicationManager.checkForApplicationUpdates()));
311-
} catch (err) {
312-
this.$logger.trace("Error checking for application updates on devices.", err);
313-
}
306+
try {
307+
const trustedDevices = _.filter(this._devices, device => device.deviceInfo.status === constants.CONNECTED_STATUS);
308+
await settlePromises(_.map(trustedDevices, device => device.applicationManager.checkForApplicationUpdates()));
309+
} catch (err) {
310+
this.$logger.trace("Error checking for application updates on devices.", err);
311+
}
314312

315-
isDeviceDetectionIntervalInProgress = false;
313+
isDeviceDetectionIntervalInProgress = false;
316314

317-
}, DevicesService.DEVICE_LOOKING_INTERVAL);
315+
}, deviceInitOpts.detectionInterval || DevicesService.DEVICE_LOOKING_INTERVAL);
318316

319-
deviceDetectionInterval.unref();
320-
this.deviceDetectionIntervals.push(deviceDetectionInterval);
317+
this.deviceDetectionInterval.unref();
318+
}
319+
}
321320

321+
@exported("devicesService")
322+
public startEmulatorDetectionInterval(opts: Mobile.IHasDetectionInterval = {}): void {
322323
let isEmulatorDetectionIntervalRunning = false;
323-
const emulatorDetectionInterval = setInterval(async () => {
324+
this.emulatorDetectionInterval = this.$timers.setInterval(async () => {
324325
if (isEmulatorDetectionIntervalRunning) {
325326
return;
326327
}
327328

328329
isEmulatorDetectionIntervalRunning = true;
329330
await this.detectCurrentlyAvailableEmulators();
330331
isEmulatorDetectionIntervalRunning = false;
331-
}, DevicesService.EMULATOR_IMAGES_DETECTION_INTERVAL);
332+
}, opts.detectionInterval || DevicesService.EMULATOR_IMAGES_DETECTION_INTERVAL);
332333

333-
emulatorDetectionInterval.unref();
334-
this.deviceDetectionIntervals.push(emulatorDetectionInterval);
334+
this.emulatorDetectionInterval.unref();
335+
}
336+
337+
@exported("devicesService")
338+
public stopDeviceDetectionInterval(): void {
339+
if (this.deviceDetectionInterval) {
340+
clearInterval(this.deviceDetectionInterval);
341+
}
342+
}
343+
344+
@exported("devicesService")
345+
public stopEmulatorDetectionInterval(): void {
346+
if (this.emulatorDetectionInterval) {
347+
clearInterval(this.emulatorDetectionInterval);
348+
}
335349
}
336350

337351
/**
@@ -356,7 +370,7 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi
356370
/**
357371
* Starts looking for running devices. All found devices are pushed to _devices variable.
358372
*/
359-
private async startLookingForDevices(deviceInitOpts?: Mobile.IDevicesServicesInitializationOptions): Promise<void> {
373+
private async startLookingForDevices(deviceInitOpts?: Mobile.IDeviceLookingOptions): Promise<void> {
360374
this.$logger.trace("startLookingForDevices; platform is %s", this._platform);
361375

362376
if (this._platform) {
@@ -366,7 +380,7 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi
366380
await this.detectCurrentlyAttachedDevices(deviceInitOpts);
367381
await this.detectCurrentlyAvailableEmulators();
368382

369-
await this.startDeviceDetectionIntervals(deviceInitOpts);
383+
await this.startDeviceDetectionInterval(deviceInitOpts);
370384
}
371385

372386
/**
@@ -517,7 +531,7 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi
517531
// are there any running devices
518532
this._platform = deviceInitOpts.platform;
519533
try {
520-
await this.startLookingForDevices(deviceInitOpts);
534+
await this.startLookingForDevices(<Mobile.IDeviceLookingOptions>deviceInitOpts);
521535
} catch (err) {
522536
this.$logger.trace("Error while checking for devices.", err);
523537
}
@@ -606,33 +620,39 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi
606620

607621
const platform = deviceInitOpts.platform;
608622
const deviceOption = deviceInitOpts.deviceId;
623+
const deviceLookingOptions: Mobile.IDeviceLookingOptions = {
624+
emulator: deviceInitOpts.emulator,
625+
platform: deviceInitOpts.platform,
626+
shouldReturnImmediateResult: deviceInitOpts.shouldReturnImmediateResult,
627+
detectionInterval: deviceInitOpts.detectionInterval
628+
};
609629

610630
if (platform && deviceOption) {
611631
this._platform = this.$mobileHelper.validatePlatformName(deviceInitOpts.platform);
612-
await this.startLookingForDevices(deviceInitOpts);
632+
await this.startLookingForDevices(deviceLookingOptions);
613633
this._device = await this.getDevice(deviceOption);
614634
if (this._device.deviceInfo.platform !== this._platform) {
615635
this.$errors.fail(constants.ERROR_CANNOT_RESOLVE_DEVICE);
616636
}
617637
this.$logger.warn("Your application will be deployed only on the device specified by the provided index or identifier.");
618638
} else if (!platform && deviceOption) {
619-
await this.startLookingForDevices(deviceInitOpts);
639+
await this.startLookingForDevices(deviceLookingOptions);
620640
this._device = await this.getDevice(deviceOption);
621641
this._platform = this._device.deviceInfo.platform;
622642
} else if (platform && !deviceOption) {
623643
this._platform = this.$mobileHelper.validatePlatformName(platform);
624-
await this.startLookingForDevices(deviceInitOpts);
644+
await this.startLookingForDevices(deviceLookingOptions);
625645
} else {
626646
// platform and deviceId are not specified
627647
if (deviceInitOpts.skipInferPlatform) {
628648
if (deviceInitOpts.skipDeviceDetectionInterval) {
629-
await this.detectCurrentlyAttachedDevices(deviceInitOpts);
649+
await this.detectCurrentlyAttachedDevices(deviceLookingOptions);
630650
} else {
631651
deviceInitOpts.shouldReturnImmediateResult = true;
632-
await this.startLookingForDevices(deviceInitOpts);
652+
await this.startLookingForDevices(deviceLookingOptions);
633653
}
634654
} else {
635-
await this.startLookingForDevices(deviceInitOpts);
655+
await this.startLookingForDevices(deviceLookingOptions);
636656

637657
const devices = this.getDeviceInstances();
638658
const platforms = _(devices)
@@ -700,18 +720,6 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi
700720
return debuggableViewsPerApp && debuggableViewsPerApp[appIdentifier];
701721
}
702722

703-
private clearDeviceDetectionInterval(): void {
704-
if (this.deviceDetectionIntervals.length) {
705-
for (const interval of this.deviceDetectionIntervals) {
706-
clearInterval(interval);
707-
}
708-
709-
this.deviceDetectionIntervals.splice(0, this.deviceDetectionIntervals.length);
710-
} else {
711-
this.$logger.trace("Device detection intervals are not started, so it cannot be stopped.");
712-
}
713-
}
714-
715723
private getDebuggableAppsCore(deviceIdentifier: string): Promise<Mobile.IDeviceApplicationInformation[]> {
716724
const device = this.getDeviceByIdentifier(deviceIdentifier);
717725
return device.applicationManager.getDebuggableApps();

0 commit comments

Comments
 (0)