Skip to content
This repository has been archived by the owner on Oct 28, 2020. It is now read-only.

Commit

Permalink
Merge pull request #98 from ZimGil/#78-avoid-double-subscriptions
Browse files Browse the repository at this point in the history
Removed double subscriptions and unsubscriptions
  • Loading branch information
ZimGil committed Nov 23, 2018
2 parents 1219c07 + ff618ef commit 16d2952
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 91 deletions.
6 changes: 6 additions & 0 deletions server/models/command-status-response.interface.ts
@@ -0,0 +1,6 @@
import { AngularCliProcessStatus } from './angular-cli-process-status.enum';

export interface CommandStatusResponse {
id: string;
status: AngularCliProcessStatus;
}
3 changes: 2 additions & 1 deletion server/server.ts
Expand Up @@ -11,6 +11,7 @@ import { AngularCliProcessStatus } from './models/angular-cli-process-status.enu
import { AngularProjectChecker } from './angular-project-checker';
import { printLogo } from './logo-printer.helper';
import { NgWizLogger } from './ngWizLogger';
import { CommandStatusResponse } from './models/command-status-response.interface';

const app = express();
const STATIC_FILES_LOCATION = path.join(__dirname, '../../..', '/dist/ngWiz');
Expand Down Expand Up @@ -123,7 +124,7 @@ app.get('/status', (req, res) => {

if (processRunner.runningProcesses[id]) {
const processStatus = processRunner.runningProcesses[id].status;
res.send({status: processStatus});
res.send(<CommandStatusResponse>{id: id, status: processStatus});
if (processStatus === AngularCliProcessStatus.done
&& !processRunner.runningProcesses[id].command.includes('ng serve ')) {
processRunner.runningProcesses[id] = null;
Expand Down
134 changes: 49 additions & 85 deletions src/app/app.component.ts
@@ -1,13 +1,15 @@
import { Component, OnInit } from '@angular/core';

import { interval, timer, empty } from 'rxjs';
import { exhaustMap, mergeMap, catchError } from 'rxjs/operators';
import * as _ from 'lodash';
import { timer, empty, throwError } from 'rxjs';
import { exhaustMap, mergeMap, catchError, filter, take } from 'rxjs/operators';

import { CommandService } from './services/command/command.service';
import { CommandRequest } from './models/angular-command-request';
import { AngularCliProcessStatus } from './models/angular-cli-process-status.enum';
import { ErrorService } from './services/error/error.service';
import { AngularCommandType } from './models/angular-command-type.enum';
import { CommandStatusResponse } from './models/command-status-response.interface';

@Component({
selector: 'app-root',
Expand All @@ -19,10 +21,8 @@ export class AppComponent implements OnInit {
title = 'ngWiz';
isAngularProject: boolean;
isReadyForWork = false;
runningCommands = {};
timedStatusCheck = interval(1000);
KEEP_ALIVE_INTERVAL = 1000;
subscription = {};
COMMAND_STATUS_CHECK_INTERVAL = 1000;
serveCommandId: string;
availableProjects: string[] = [];

Expand Down Expand Up @@ -50,80 +50,31 @@ export class AppComponent implements OnInit {
.subscribe((projects: string[]) => this.availableProjects = projects);
}

checkCommandStatus(commandId: string): void {
this.commandService.checkCommandStatus(commandId)
.subscribe(response => {
this.runningCommands[commandId] = response;
}, error => {
if (error.status === 404) {
console.log('command not found in server, stop checking');
this.doneCheckingCommand(commandId);
}
});
}

doneCheckingCommand(commandId: string): void {
this.subscription[commandId].unsubscribe();
this.subscription[commandId] = null;
}

commandDone(commandId: string, commandType?: AngularCommandType): void {
if (commandType === AngularCommandType.new) {
this.checkAngularProject();
}
this.runningCommands[commandId] = null;
}

startCheckingCommand(commandId: string, commandType?: AngularCommandType): void {
if (this.runningCommands[commandId]) {
const status = this.runningCommands[commandId].status;

if (status === AngularCliProcessStatus.done) {
this.doneCheckingCommand(commandId);
this.commandDone(commandId, commandType);
if (commandType === AngularCommandType.serve) {
this.serveCommandId = commandId;
}
} else if (status === AngularCliProcessStatus.error) {
this.doneCheckingCommand(commandId);
} else if (status === AngularCliProcessStatus.working) {
this.checkCommandStatus(commandId);
}
} else {
this.checkCommandStatus(commandId);
}
}

chooseProject(projectName: string) {
this.commandService.chooseProject(projectName)
.subscribe(
res => this.isAngularProject = true,
() => {
this.errorService.addError({
errorText: 'Could not choose this project',
errorDescription: 'There was an error while trying to choose this project',
});
this.availableProjects.splice(this.availableProjects.indexOf(projectName));
this.commandService.chooseProject(projectName).subscribe(
res => this.isAngularProject = true,
() => {
this.errorService.addError({
errorText: 'Could not choose this project',
errorDescription: 'There was an error while trying to choose this project',
});
}
this.availableProjects.splice(this.availableProjects.indexOf(projectName));
}
);
}

keepAlive(): void {
this.subscription['TimedkeepAlive'] = timer(0, this.KEEP_ALIVE_INTERVAL)
.pipe(
exhaustMap(
() => this.commandService.keepAlive()
)
)
.subscribe(
response => {},
error => {
this.errorService.addError({
errorText: 'The server is offline',
errorDescription: 'please run the server and restart the client'
});
this.subscription['TimedkeepAlive'].unsubscribe();
}
);
timer(0, this.KEEP_ALIVE_INTERVAL).pipe(
exhaustMap(() => this.commandService.keepAlive()),
catchError(error => throwError(error).pipe(take(1)))
)
.subscribe(
_.noop,
error => this.errorService.addError({
errorText: 'The server is offline',
errorDescription: 'please run the server and restart the client'
})
);
}

leaveProject(): void {
Expand Down Expand Up @@ -166,19 +117,32 @@ export class AppComponent implements OnInit {
sendCommand(userCommand: string, commandType?: AngularCommandType): void {
const request = new CommandRequest(userCommand);

// TO-DO:
// remove subscribe inside of subscribe
this.commandService.sendCommand(request)
.subscribe(commandId => {
if (commandType === AngularCommandType.serve) {
localStorage.setItem('ngServeCommandId', commandId);
}
console.log('started working on command, ID:', commandId);
this.subscription[commandId] = this.timedStatusCheck
.subscribe(() => this.startCheckingCommand(commandId, commandType));
this.commandService.sendCommand(request).pipe(
mergeMap(commandId => timer(0, this.COMMAND_STATUS_CHECK_INTERVAL)
.pipe(
mergeMap(() => this.commandService.checkCommandStatus(commandId)),
filter((response: CommandStatusResponse) => response.status !== AngularCliProcessStatus.working),
take(1)
)
)
)
.subscribe(response => {
switch (response.status) {
case AngularCliProcessStatus.done:
this.commandDone(response, commandType);
break;
}
});
}

commandDone(response: CommandStatusResponse, commandType?: AngularCommandType) {
if (commandType === AngularCommandType.new) {
this.checkAngularProject();
} else if (commandType === AngularCommandType.serve) {
this.serveCommandId = response.id;
}
}

sendServeCommand(serveCommand: string): void {
this.sendCommand(serveCommand, AngularCommandType.serve);
}
Expand Down
6 changes: 4 additions & 2 deletions src/app/components/serve/serve.component.ts
@@ -1,5 +1,7 @@
import { Component, Output, EventEmitter, Input } from '@angular/core';

//
import * as _ from 'lodash';
//
import { AngularCliCommand } from '../../models/angular-cli-command.interface';
import { NgserveOptions } from '../../default-values/ng-serve-options';
import { CommandService } from './../../services/command/command.service';
Expand Down Expand Up @@ -34,7 +36,7 @@ export class ServeComponent {
this.isStoppingServeCommand = true;
this.commandService.stopServing(this.serveCommandId)
.subscribe(
() => {},
_.noop,
error => {
this.errorService.addError({
errorText: 'The "ng serve" command you\'re trying to stop was not found',
Expand Down
6 changes: 6 additions & 0 deletions src/app/models/command-status-response.interface.ts
@@ -0,0 +1,6 @@
import { AngularCliProcessStatus } from './angular-cli-process-status.enum';

export interface CommandStatusResponse {
id: string;
status: AngularCliProcessStatus;
}
10 changes: 7 additions & 3 deletions src/app/services/command/command.service.ts
@@ -1,7 +1,11 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

//
import { Observable } from 'rxjs';
//
import { CommandRequest } from '../../models/angular-command-request';
import { CommandStatusResponse } from '../../models/command-status-response.interface';


@Injectable({
providedIn: 'root'
Expand All @@ -21,8 +25,8 @@ export class CommandService {
return this.http.get(`${this.BASE_URL}:${this.PORT}/projects`);
}

checkCommandStatus(commandId: string) {
return this.http.get(`${this.BASE_URL}:${this.PORT}/status?id=${commandId}`);
checkCommandStatus(commandId: string): Observable<CommandStatusResponse> {
return this.http.get<CommandStatusResponse>(`${this.BASE_URL}:${this.PORT}/status?id=${commandId}`);
}

chooseProject(projectName: string) {
Expand Down

0 comments on commit 16d2952

Please sign in to comment.