Skip to content

Commit

Permalink
Emit liveSyncStopped event when LiveSync operation is really stopped
Browse files Browse the repository at this point in the history
In case `stopLiveSync` is called during livesync, we should await the current action and emit `liveSyncStopped` event. At the moment, we have the following behavior:
1. In case stopLiveSync is called with deviceIdentifiers, we emit `liveSyncStopped` immediately for all of them. However there may be pending actions, for example build + deploy for current device. We cannot stop the actions, so you receive `liveSyncStopped` and application is installed/updated on device after that.
Fix this by persisting the current action and await it before emitting `liveSyncStopped` event.
2. In case we are currently rebuilding the application and some changes are applied during build, we'll update the `actionsChain`. At this point we'll have several actions in the chain. In case stopLiveSync method is called (without deviceIdentifiers), we will await all pending actions, which will result in awaiting the build, deploy and all other actions and we'll emit the `liveSyncStopped` after that. However we should not execute all pending actions - we should just execute the current one and skip the rest.
In order to fix this, just set isStopped to true before awaiting the actions. This way only the current action will be executed.
  • Loading branch information
rosen-vladimirov committed Jul 27, 2017
1 parent b62c925 commit b01c1ef
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 15 deletions.
1 change: 1 addition & 0 deletions lib/definitions/livesync.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ interface ILiveSyncProcessInfo {
actionsChain: Promise<any>;
isStopped: boolean;
deviceDescriptors: ILiveSyncDeviceInfo[];
currentSyncAction: Promise<any>;
}

/**
Expand Down
35 changes: 20 additions & 15 deletions lib/services/livesync/livesync-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ export class LiveSyncService extends EventEmitter implements ILiveSyncService {
const liveSyncProcessInfo = this.liveSyncProcessesInfo[projectDir];

if (liveSyncProcessInfo) {
_.each(deviceIdentifiers, deviceId => {
_.remove(liveSyncProcessInfo.deviceDescriptors, descriptor => {
const shouldRemove = descriptor.identifier === deviceId;
if (shouldRemove) {
this.emit(LiveSyncEvents.liveSyncStopped, { projectDir, deviceIdentifier: descriptor.identifier });
}
// In case we are coming from error during livesync, the current action is the one that errored (but we are still executing it),
// so we cannot await it as this will cause infinite loop.
const shouldAwaitPendingOperation = !stopOptions || stopOptions.shouldAwaitAllActions;

return shouldRemove;
});
let removedDeviceIdentifiers: string[] = deviceIdentifiers || [];

_.each(deviceIdentifiers, deviceId => {
removedDeviceIdentifiers = _.remove(liveSyncProcessInfo.deviceDescriptors, descriptor => descriptor.identifier === deviceId)
.map(deviceDescriptor => deviceDescriptor.identifier);
});

// In case deviceIdentifiers are not passed, we should stop the whole LiveSync.
Expand All @@ -66,16 +66,12 @@ export class LiveSyncService extends EventEmitter implements ILiveSyncService {
}

liveSyncProcessInfo.watcherInfo = null;
liveSyncProcessInfo.isStopped = true;

if (liveSyncProcessInfo.actionsChain && (!stopOptions || stopOptions.shouldAwaitAllActions)) {
if (liveSyncProcessInfo.actionsChain && shouldAwaitPendingOperation) {
await liveSyncProcessInfo.actionsChain;
}

_.each(liveSyncProcessInfo.deviceDescriptors, descriptor => {
this.emit(LiveSyncEvents.liveSyncStopped, { projectDir, deviceIdentifier: descriptor.identifier });
});

liveSyncProcessInfo.isStopped = true;
liveSyncProcessInfo.deviceDescriptors = [];

// Kill typescript watcher
Expand All @@ -85,7 +81,14 @@ export class LiveSyncService extends EventEmitter implements ILiveSyncService {
projectData
}
});
} else if (liveSyncProcessInfo.currentSyncAction && shouldAwaitPendingOperation) {
await liveSyncProcessInfo.currentSyncAction;
}

// Emit LiveSync stopped when we've really stopped.
_.each(removedDeviceIdentifiers, deviceIdentifier => {
this.emit(LiveSyncEvents.liveSyncStopped, { projectDir, deviceIdentifier });
});
}
}

Expand Down Expand Up @@ -139,6 +142,7 @@ export class LiveSyncService extends EventEmitter implements ILiveSyncService {
private setLiveSyncProcessInfo(projectDir: string, deviceDescriptors: ILiveSyncDeviceInfo[]): void {
this.liveSyncProcessesInfo[projectDir] = this.liveSyncProcessesInfo[projectDir] || Object.create(null);
this.liveSyncProcessesInfo[projectDir].actionsChain = this.liveSyncProcessesInfo[projectDir].actionsChain || Promise.resolve();
this.liveSyncProcessesInfo[projectDir].currentSyncAction = this.liveSyncProcessesInfo[projectDir].actionsChain;
this.liveSyncProcessesInfo[projectDir].isStopped = false;

const currentDeviceDescriptors = this.liveSyncProcessesInfo[projectDir].deviceDescriptors || [];
Expand Down Expand Up @@ -446,7 +450,8 @@ export class LiveSyncService extends EventEmitter implements ILiveSyncService {
if (liveSyncInfo) {
liveSyncInfo.actionsChain = liveSyncInfo.actionsChain.then(async () => {
if (!liveSyncInfo.isStopped) {
const res = await action();
liveSyncInfo.currentSyncAction = action();
const res = await liveSyncInfo.currentSyncAction;
return res;
}
});
Expand Down

0 comments on commit b01c1ef

Please sign in to comment.