Permalink
Browse files

perf(times): async pipe for updating live times

  • Loading branch information...
jkuri committed Aug 27, 2017
1 parent 5eeddc5 commit 6dbf019ccfcedf283a215dff8dc74f5d17546848
@@ -11,6 +11,9 @@ import { AuthGuardProvider, AuthGuard } from './services/auth-guard.service';
import { AuthServiceProvider } from './services/auth.service';
import { EqualValidator } from './directives/equal-validator.directive';
import { SafeHtmlPipe } from './pipes/safe-html.pipe';
import { TimeDurationPipe } from './pipes/time-duration.pipe';
import { ToTimePipe } from './pipes/to-time.pipe';
import { TimeToNowPipe } from './pipes/time-to-now.pipe';
import { AppComponent } from './app.component';
import { AppSetupComponent } from './components/app-setup';
import { AppTerminalComponent } from './components/app-terminal';
@@ -42,7 +45,10 @@ import { AppTeamComponent } from './components/app-team';
AppSettingsComponent,
AppTeamComponent,
EqualValidator,
SafeHtmlPipe
SafeHtmlPipe,
TimeDurationPipe,
ToTimePipe,
TimeToNowPipe
],
imports: [
BrowserModule,
@@ -90,7 +90,8 @@ <h1 class="bold">
<div class="column is-1">
<p class="total-time">
<img src="images/icons/clock.svg">
<span>{{ totalTime }}</span>
<span *ngIf="status !== 'running'">{{ totalTime | toTime }}</span>
<span *ngIf="status === 'running'">{{ totalTime | timeDuration }}</span>
</p>
</div>
</div>
@@ -130,7 +131,8 @@ <h1 class="bold">
</div>
</div>
<div class="column is-1">
<span class="job-time">{{ job.time }}</span>
<span class="job-time" *ngIf="job?.status === 'running'">{{ job.start_time | timeDuration }}</span>
<span class="job-time" *ngIf="job?.status !== 'running'">{{ job.end_time - job.start_time | toTime }}</span>
</div>
<div class="column is-1" *ngIf="build?.hasPermission">
<span class="icon" name="restart-job" (click)="restartJob($event, job.id)" [class.disabled]="job.processing">
@@ -18,7 +18,7 @@ export class AppBuildDetailsComponent implements OnInit, OnDestroy {
build: any;
status: string;
timeWords: string;
totalTime: string;
totalTime: number;
previousRuntime: number;
processingBuild: boolean;
approximatelyRemainingTime: string;
@@ -62,7 +62,7 @@ export class AppBuildDetailsComponent implements OnInit, OnDestroy {
}

this.status = this.getBuildStatus();
this.startUpdating();
this.updateJobTimes();

this.subStatus = this.socketService.outputEvents
.filter(event => event.type === 'process')
@@ -85,6 +85,7 @@ export class AppBuildDetailsComponent implements OnInit, OnDestroy {

this.build.jobs[index].processing = false;
this.status = this.getBuildStatus();
this.updateJobTimes();
}
});

@@ -108,49 +109,19 @@ export class AppBuildDetailsComponent implements OnInit, OnDestroy {

this.document.getElementById('favicon').setAttribute('href', 'images/favicon.png');
this.titleService.setTitle('Abstruse CI');
this.stopUpdating();
}

startUpdating(): void {
if (this.updateInterval) {
clearInterval(this.updateInterval);
}

this.updateJobTimes();
this.updateInterval = setInterval(() => this.updateJobTimes(), 1000);
}

stopUpdating(): void {
if (this.updateInterval) {
clearInterval(this.updateInterval);
}
}

updateJobTimes(): void {
let currentTime = new Date().getTime() - this.socketService.timeSyncDiff;
this.build.jobs = this.build.jobs.map(job => {
if (job.status === 'queued') {
job.time = '00:00';
} else if (!job.end_time || job.status === 'running') {
job.time = format(currentTime - job.start_time, 'mm:ss');
} else {
job.time = format(job.end_time - job.start_time, 'mm:ss');
}

return job;
});
if (this.status !== 'running') {
this.totalTime = Math.max(...this.build.jobs.map(job => job.end_time - job.start_time));
} else {
this.totalTime = Math.max(...this.build.jobs.map(job => job.start_time));
}

let runningTime = Math.max(...this.build.jobs.map(job => {
let date = new Date(0);
let splitted = job.time.split(':');
date.setUTCMinutes(splitted[0]);
date.setUTCSeconds(splitted[1]);
return date;
}));
this.totalTime = format(runningTime, 'mm:ss');

if (this.previousRuntime && this.previousRuntime > runningTime) {
this.approximatelyRemainingTime = format(this.previousRuntime - runningTime, 'mm:ss');
if (this.previousRuntime && this.previousRuntime > this.totalTime) {
this.approximatelyRemainingTime = format(this.previousRuntime - this.totalTime, 'mm:ss');
}
}

@@ -18,15 +18,15 @@
<span class="bold" *ngIf="build?.data?.pull_request?.head?.sha">{{ build?.data?.pull_request.head.sha }}</span>
<span class="bold" *ngIf="!build?.data?.pull_request?.head?.sha && build?.data?.after">{{ build?.data?.after }}</span>
<span class="bold" *ngIf="!build?.data?.pull_request?.head?.sha && !build?.data?.after && build?.data?.sha">{{ build?.data?.sha }}</span>
<span class="bold" *ngIf="!build?.data?.pull_request?.head?.sha && !build?.data?.afte && !build?.data?.shar && build?.data?.object_attributes?.last_commit?.id">{{ build?.data?.object_attributes?.last_commit?.id }}</span>
<span class="bold" *ngIf="!build?.data?.pull_request?.head?.sha && !build?.data?.after && !build?.data?.sha && build?.data?.object_attributes?.last_commit?.id">{{ build?.data?.object_attributes?.last_commit?.id }}</span>

<span *ngIf="build?.data?.commits && !tag">{{ build?.data?.commits[build?.data?.commits.length - 1]?.message }}</span>
<span *ngIf="!build?.data?.commits && !tag && build?.data?.pull_request?.title">{{ build?.data?.pull_request?.title }}</span>
<span *ngIf="!build?.data?.commits && !tag && !build?.data?.pull_request?.title && build?.data?.message">{{ build?.data?.message }}</span>
<span *ngIf="!build?.data?.commits && !build?.data?.pull_request?.title && !build?.data?.message && build?.data?.object_attributes?.last_commit?.message && !tag">{{ build?.data?.object_attributes?.last_commit?.message }}</span>
<span *ngIf="tag">{{ build?.data?.head_commit?.message }}</span>

<span class="smaller">{{ build?.timeInWords }} ago</span>
<span class="smaller">{{ build?.created_at | timeToNow }} ago</span>
</div>
<div class="column is-2">
<span *ngIf="build?.data?.user_name && !tag">{{ build?.data?.user_name }}</span>
@@ -37,7 +37,8 @@
<span *ngIf="tag">{{ build?.data?.head_commit?.comitter?.name }}</span>
</div>
<div class="column is-1">
<span class="build-time">{{ build?.totalTime }}</span>
<span class="build-time" *ngIf="build?.status === 'running'">{{ build?.maxTime | timeDuration }}</span>
<span class="build-time" *ngIf="build?.status !== 'running'">{{ build?.maxTime | toTime }}</span>
</div>
<div class="column is-1 justify-end" *ngIf="build?.hasPermission">
<span class="icon restart-build" (click)="restartBuild($event, build.id)" [class.disabled]="processingRequest">
@@ -19,7 +19,6 @@ export class AppBuildsComponent implements OnInit, OnDestroy {
builds: any[];
limit: number;
offset: number;
updateInterval: any;
userData: any;

constructor(
@@ -85,6 +84,8 @@ export class AppBuildsComponent implements OnInit, OnDestroy {
this.builds[build].jobs[index].end_time = new Date();
break;
}

this.update();
}
});
}
@@ -97,32 +98,10 @@ export class AppBuildsComponent implements OnInit, OnDestroy {
if (this.sub) {
this.sub.unsubscribe();
}

this.stopUpdating();
}

update(): void {
const currentTime = new Date().getTime() - this.socketService.timeSyncDiff;

this.builds = this.builds.map(build => {
build.jobs = build.jobs.map(job => {
if (!job.end_time || job.status === 'running') {
job.time = format(currentTime - job.start_time, 'mm:ss');
} else {
job.time = format(job.end_time - job.start_time, 'mm:ss');
}

return job;
});

build.totalTime = format(Math.max(...build.jobs.map(job => {
let date = new Date();
let splitted = job.time.split(':');
date.setUTCMinutes(splitted[0]);
date.setUTCSeconds(splitted[1]);
return date;
})), 'mm:ss');

let status = 'queued';
if (build.jobs.findIndex(job => job.status === 'failed') !== -1) {
status = 'failed';
@@ -136,28 +115,17 @@ export class AppBuildsComponent implements OnInit, OnDestroy {
status = 'success';
}

build.status = status;
build.timeInWords = distanceInWordsToNow(build.created_at);
if (status !== 'running') {
build.maxTime = Math.max(...build.jobs.map(job => job.end_time - job.start_time));
} else {
build.maxTime = Math.max(...build.jobs.map(job => job.start_time));
}

build.status = status;
return build;
});
}

startUpdating(): void {
if (this.updateInterval) {
clearInterval(this.updateInterval);
}

this.update();
this.updateInterval = setInterval(() => this.update(), 1000);
}

stopUpdating(): void {
if (this.updateInterval) {
clearInterval(this.updateInterval);
}
}

fetch(e?: MouseEvent): void {
if (e && e.preventDefault) {
e.preventDefault();
@@ -175,7 +143,7 @@ export class AppBuildsComponent implements OnInit, OnDestroy {
this.hideMoreButton = true;
}

this.startUpdating();
this.update();
});
}

@@ -186,7 +154,7 @@ export class AppBuildsComponent implements OnInit, OnDestroy {
}

this.builds.unshift(build);
this.startUpdating();
this.update();
});
}

@@ -94,7 +94,8 @@ <h2 *ngIf="tag">{{ job?.build?.data?.head_commit?.message }}</h2>
<div class="column is-1">
<p class="total-time">
<img src="images/icons/clock.svg">
<span>{{ job?.time }}</span>
<span *ngIf="jobRun.status === 'running'">{{ jobRun.start_time | timeDuration }}</span>
<span *ngIf="jobRun.status !== 'running'">{{ jobRun.end_time - jobRun.start_time | toTime }}</span>
</p>
</div>

@@ -112,10 +112,8 @@ export class AppJobComponent implements OnInit, OnDestroy {
this.previousRuntime = this.job.lastJob.end_time - this.job.lastJob.start_time;
}

this.socketService.emit({ type: 'subscribeToJobOutput', data: { jobId: this.id } });

this.updateJobTime();
setInterval(() => this.updateJobTime(), 1000);
this.socketService.emit({ type: 'subscribeToJobOutput', data: { jobId: this.id } });
});
});
}
@@ -134,14 +132,9 @@ export class AppJobComponent implements OnInit, OnDestroy {
}

updateJobTime(): void {
let currentTime = new Date().getTime() - this.socketService.timeSyncDiff;
if (!this.jobRun.end_time || this.jobRun.status === 'running') {
this.job.time = format(currentTime - this.jobRun.start_time, 'mm:ss');
} else {
this.job.time = format(this.jobRun.end_time - this.jobRun.start_time, 'mm:ss');
}
if (this.previousRuntime) {
this.expectedProgress = (currentTime - this.jobRun.start_time) / this.previousRuntime;
this.expectedProgress =
(new Date().getTime() - this.jobRun.start_time) / this.previousRuntime;
}
}

@@ -31,7 +31,6 @@ export class AppRepositoryComponent implements OnInit, OnDestroy {
form: IRepoForm;
limit: number;
offset: number;
updateInterval: any;
hideMoreButton: boolean;
userData: any;

@@ -104,14 +103,17 @@ export class AppRepositoryComponent implements OnInit, OnDestroy {
}

this.repo.builds[index].jobs[jobIndex].status = status;

this.updateJobs();
}
}
});
}

ngOnDestroy() {
this.sub.unsubscribe();
this.stopInterval();
if (this.sub) {
this.sub.unsubscribe();
}
}

fetch(): void {
@@ -143,7 +145,7 @@ export class AppRepositoryComponent implements OnInit, OnDestroy {
this.hideMoreButton = true;
}

this.startInterval();
this.updateJobs();
});
}

@@ -154,6 +156,7 @@ export class AppRepositoryComponent implements OnInit, OnDestroy {
}

this.repo.builds.unshift(build);
this.updateJobs();
});
}

@@ -171,43 +174,9 @@ export class AppRepositoryComponent implements OnInit, OnDestroy {
});
}

startInterval(): void {
if (this.updateInterval) {
clearInterval(this.updateInterval);
}

this.updateJobs();
this.updateInterval = setInterval(() => this.updateJobs(), 1000);
}

stopInterval(): void {
if (this.updateInterval) {
clearInterval(this.updateInterval);
}
}

updateJobs(): void {
let currentTime = new Date().getTime() - this.socketService.timeSyncDiff;

this.repo.builds = this.repo.builds
.map(build => {
build.jobs = build.jobs.map(job => {
if (!job.end_time || job.status === 'running') {
job.time = format(currentTime - job.start_time, 'mm:ss');
} else {
job.time = format(job.end_time - job.start_time, 'mm:ss');
}
return job;
});

build.totalTime = format(Math.max(...build.jobs.map(job => {
let date = new Date();
let splitted = job.time.split(':');
date.setUTCMinutes(splitted[0]);
date.setUTCSeconds(splitted[1]);
return date;
})), 'mm:ss');

let status = 'queued';
if (build.jobs.findIndex(job => job.status === 'failed') !== -1) {
status = 'failed';
@@ -221,8 +190,13 @@ export class AppRepositoryComponent implements OnInit, OnDestroy {
status = 'success';
}

if (status !== 'running') {
build.maxTime = Math.max(...build.jobs.map(job => job.end_time - job.start_time));
} else {
build.maxTime = Math.max(...build.jobs.map(job => job.start_time));
}

build.status = status;
build.timeInWords = distanceInWordsToNow(build.created_at);
return build;
});
}
Oops, something went wrong.

0 comments on commit 6dbf019

Please sign in to comment.