Skip to content

Commit d91e1c6

Browse files
committed
[us40] Add some delay before rescheduling a task to avoid duplicates of tasks scheduled in a short delay + Fix runAll and backup method returning multiple results
1 parent 1be0514 commit d91e1c6

6 files changed

+45
-42
lines changed

src/app/background-task/background-task.service.spec.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ describe('BackgroundTaskService', () => {
333333
});
334334

335335
// Assert
336-
tick();
336+
tick(1000);
337337
expect(result1).toEqual(2);
338338
expect(result2).toEqual(1);
339339
}));
@@ -349,13 +349,13 @@ describe('BackgroundTaskService', () => {
349349
return mustBeConsumedAsyncObservable(undefined);
350350
};
351351
backgroundTaskService.schedule("task1", task1);
352-
tick();
352+
tick(500);
353353

354354
// Act
355355
backgroundTaskService.schedule("task1", task1);
356356

357357
// Assert
358-
tick();
358+
tick(500);
359359
expect(result1).toEqual(2);
360360
}));
361361

@@ -371,12 +371,12 @@ describe('BackgroundTaskService', () => {
371371
result1a++;
372372
return mustBeConsumedAsyncObservable(undefined);
373373
});
374-
tick();
374+
tick(500);
375375
backgroundTaskService.schedule("task1", () => {
376376
result1b++;
377377
return mustBeConsumedAsyncObservable(undefined);
378378
});
379-
tick();
379+
tick(500);
380380

381381
// Act
382382
backgroundTaskService.schedule("task1", () => {
@@ -385,7 +385,7 @@ describe('BackgroundTaskService', () => {
385385
});
386386

387387
// Assert
388-
tick();
388+
tick(500);
389389
expect(result1a).toEqual(1);
390390
expect(result1b).toEqual(1);
391391
expect(result1c).toEqual(1);
@@ -404,7 +404,7 @@ describe('BackgroundTaskService', () => {
404404
result1++;
405405
}));
406406
});
407-
tick();
407+
tick(500);
408408

409409
// Act
410410
backgroundTaskService.schedule("task1", () => {
@@ -413,7 +413,7 @@ describe('BackgroundTaskService', () => {
413413
});
414414

415415
// Assert
416-
tick();
416+
tick(500);
417417
expect(result1).toEqual(0);
418418
tick(5000);
419419
expect(result1).toEqual(2);

src/app/background-task/background-task.service.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Component, Injectable} from '@angular/core';
2-
import {BehaviorSubject, mergeMap, Observable, of, share} from "rxjs";
2+
import {BehaviorSubject, delay, mergeMap, Observable, of, shareReplay} from "rxjs";
33
import {MatSnackBar, MatSnackBarModule, MatSnackBarRef} from "@angular/material/snack-bar";
44
import {NgForOf, NgIf} from "@angular/common";
55
import {HttpEventType, HttpProgressEvent, HttpResponse} from "@angular/common/http";
@@ -12,6 +12,7 @@ export class BackgroundTaskService {
1212
private snackBarRef?: MatSnackBarRef<SnackBarProgressIndicatorComponent>;
1313
private readonly scheduledTasks = new Set<string>();
1414
private readonly runningTasks = new Map<string, Observable<void>>();
15+
private readonly DELAY_BEFORE_RESCHEDULE = 500;
1516

1617
constructor(private snackBar: MatSnackBar) {
1718
}
@@ -76,8 +77,9 @@ export class BackgroundTaskService {
7677
}
7778
const scheduledTask = alreadyRunningTask.pipe(mergeMap(() => {
7879
const runningTask = task()
79-
// Multicast the result to all future subscribers since we don't want to rerun the task once for each subscriber
80-
.pipe(share());
80+
.pipe(delay(this.DELAY_BEFORE_RESCHEDULE))
81+
// Cache the result to all future subscribers since we don't want to rerun the task for each future subscriber
82+
.pipe(shareReplay(1));
8183
this.runningTasks.set(taskName, runningTask);
8284
this.scheduledTasks.delete(taskName);
8385
return runningTask;

src/app/database/database-backup-and-restore.service.spec.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {HttpEventType, HttpResponse} from "@angular/common/http";
1111
import {mockFileElement} from "../file-list/file-list.component.spec";
1212
import {fakeAsync, tick} from "@angular/core/testing";
1313
import {db} from "./db";
14-
import {BehaviorSubject, lastValueFrom} from "rxjs";
14+
import {BehaviorSubject, firstValueFrom} from "rxjs";
1515
import {mockBackgroundTaskService} from "../background-task/background-task.service.spec";
1616
import {Progress} from "../background-task/background-task.service";
1717
import {mockFilesCacheService} from "../files-cache/files-cache.service.spec";
@@ -81,7 +81,7 @@ describe('DatabaseBackupAndRestoreService', () => {
8181
mockFilesCacheService([dbBackupFile]);
8282

8383
// Act
84-
const restorePromise = lastValueFrom(databaseBackupAndRestoreService.restore());
84+
const restorePromise = firstValueFrom(databaseBackupAndRestoreService.restore());
8585

8686
// Assert
8787
// We need to explicitly wait for the restore to finish
@@ -118,7 +118,7 @@ describe('DatabaseBackupAndRestoreService', () => {
118118
db.rules.add(oldRule)
119119

120120
// Act
121-
const restorePromise = lastValueFrom(databaseBackupAndRestoreService.restore());
121+
const restorePromise = firstValueFrom(databaseBackupAndRestoreService.restore());
122122

123123
// Assert
124124
// We need to explicitly wait for the restore to finish
@@ -148,7 +148,7 @@ describe('DatabaseBackupAndRestoreService', () => {
148148
mockFilesCacheService([dbBackupFile]);
149149

150150
// Act
151-
const restorePromise = lastValueFrom(databaseBackupAndRestoreService.restore());
151+
const restorePromise = firstValueFrom(databaseBackupAndRestoreService.restore());
152152

153153
// Assert
154154
tick();
@@ -185,7 +185,7 @@ describe('DatabaseBackupAndRestoreService', () => {
185185
} as HttpResponse<any>));
186186

187187
// Act
188-
const backupPromise = lastValueFrom(databaseBackupAndRestoreService.backup());
188+
const backupPromise = firstValueFrom(databaseBackupAndRestoreService.backup());
189189

190190
// Assert
191191
// No failure in mock setup
@@ -226,7 +226,7 @@ describe('DatabaseBackupAndRestoreService', () => {
226226
} as HttpResponse<any>));
227227

228228
// Act
229-
const backupPromise = lastValueFrom(databaseBackupAndRestoreService.backup());
229+
const backupPromise = firstValueFrom(databaseBackupAndRestoreService.backup());
230230

231231
// Assert
232232
// No failure in mock setup

src/app/database/database-backup-and-restore.service.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {Injectable} from '@angular/core';
22
import {exportDB} from "dexie-export-import";
33
import {db} from "./db";
44
import {FileUploadService} from "../file-upload/file-upload.service";
5-
import {finalize, from, map, mergeMap, Observable, of, tap} from "rxjs";
5+
import {finalize, from, last, map, mergeMap, Observable, of, tap} from "rxjs";
66
import {FileService} from "../file-list/file.service";
77
import {FileElement, isFileElement} from "../file-list/file-list.component";
88
import {BackgroundTaskService} from "../background-task/background-task.service";
@@ -40,9 +40,8 @@ export class DatabaseBackupAndRestoreService {
4040
return this.fileUploadService.upload({name: DatabaseBackupAndRestoreService.DB_NAME, blob}, dbFile?.id);
4141
}),
4242
tap(httpEvent => this.backgroundTaskService.updateProgress(progress, httpEvent)),
43-
finalize(() => this.updateLastDbBackupTime()),
44-
map(() => {
45-
}));
43+
last(null, undefined),
44+
map(() => this.updateLastDbBackupTime()));
4645
}
4746

4847
scheduleBackup() {

src/app/rules/rule.service.spec.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {RuleRepository} from "./rule.repository";
1212
import {FilesCacheService} from "../files-cache/files-cache.service";
1313
import {mockFilesCacheService} from "../files-cache/files-cache.service.spec";
1414
import {mockBackgroundTaskService} from "../background-task/background-task.service.spec";
15-
import {BehaviorSubject, lastValueFrom} from "rxjs";
15+
import {BehaviorSubject, firstValueFrom} from "rxjs";
1616
import {Progress} from "../background-task/background-task.service";
1717
import {FileElement} from "../file-list/file-list.component";
1818

@@ -99,7 +99,7 @@ describe('RuleService', () => {
9999
const service = mockElectricityBillSample(file, fileService);
100100

101101
// Act
102-
const runAllPromise = lastValueFrom(service.runAll(), {defaultValue: undefined});
102+
const runAllPromise = firstValueFrom(service.runAll(), {defaultValue: undefined});
103103

104104
// Assert
105105
tick();
@@ -114,7 +114,7 @@ describe('RuleService', () => {
114114
const service = mockElectricityBillSample(file, fileService);
115115

116116
// Act
117-
const runAllPromise = lastValueFrom(service.runAll(), {defaultValue: undefined});
117+
const runAllPromise = firstValueFrom(service.runAll(), {defaultValue: undefined});
118118

119119
// Assert
120120
tick();
@@ -149,7 +149,7 @@ describe('RuleService', () => {
149149
mockFilesCacheService([file]);
150150

151151
// Act
152-
const runAllPromise = lastValueFrom(service.runAll(), {defaultValue: undefined});
152+
const runAllPromise = firstValueFrom(service.runAll(), {defaultValue: undefined});
153153

154154
// Assert
155155
tick();
@@ -251,7 +251,7 @@ describe('RuleService', () => {
251251
mockFilesCacheService([file, otherFile], true);
252252

253253
// Act
254-
const runAllPromise = lastValueFrom(service.runAll(), {defaultValue: undefined});
254+
const runAllPromise = firstValueFrom(service.runAll(), {defaultValue: undefined});
255255

256256
// Assert
257257
tick();
@@ -301,7 +301,7 @@ describe('RuleService', () => {
301301
mockFilesCacheService([file]);
302302

303303
// Act
304-
const runAllPromise = lastValueFrom(service.runAll(), {defaultValue: undefined});
304+
const runAllPromise = firstValueFrom(service.runAll(), {defaultValue: undefined});
305305

306306
// Assert
307307
tick();
@@ -368,7 +368,7 @@ describe('RuleService', () => {
368368
mockFilesCacheService([file], true);
369369

370370
// Act
371-
const runAllPromise = lastValueFrom(service.runAll(), {defaultValue: undefined});
371+
const runAllPromise = firstValueFrom(service.runAll(), {defaultValue: undefined});
372372

373373
// Assert
374374
// fakeAsync(() => tick());

src/app/rules/rule.service.ts

+16-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {Injectable} from '@angular/core';
22
import {FileService} from "../file-list/file.service";
3-
import {BehaviorSubject, concatMap, filter, find, from, map, mergeMap, Observable, of, tap, zip} from "rxjs";
3+
import {BehaviorSubject, concatMap, filter, find, from, last, map, mergeMap, Observable, of, tap, zip} from "rxjs";
44
import {FileElement, isFileElement} from "../file-list/file-list.component";
55
import {Rule, RuleRepository} from "./rule.repository";
66
import {FilesCacheService} from "../files-cache/files-cache.service";
@@ -54,19 +54,21 @@ export class RuleService {
5454

5555
runAll(): Observable<void> {
5656
return from(this.ruleRepository.findAll())
57-
.pipe(mergeMap(rules => {
58-
const fileOrFolders = this.filesCacheService.getAll()
59-
// Get all files
60-
const files = fileOrFolders
61-
.filter((file): file is FileElement => isFileElement(file));
62-
63-
// Run the script for each file to get the associated category
64-
// The amount of step is one download per file and one per rule running for each file
65-
const stepAmount = files.length * (1 + rules.length);
66-
const progress = this.backgroundTaskService.showProgress('Running all rules', stepAmount);
67-
return this.runAllAndSetCategories(files, rules, progress)
68-
.pipe(tap({complete: () => progress.next({value: 100, index: stepAmount})}));
69-
}));
57+
.pipe(
58+
mergeMap(rules => {
59+
const fileOrFolders = this.filesCacheService.getAll()
60+
// Get all files
61+
const files = fileOrFolders
62+
.filter((file): file is FileElement => isFileElement(file));
63+
64+
// Run the script for each file to get the associated category
65+
// The amount of step is one download per file and one per rule running for each file
66+
const stepAmount = files.length * (1 + rules.length);
67+
const progress = this.backgroundTaskService.showProgress('Running all rules', stepAmount);
68+
return this.runAllAndSetCategories(files, rules, progress)
69+
.pipe(tap({complete: () => progress.next({value: 100, index: stepAmount})}));
70+
}),
71+
last(null, undefined));
7072
}
7173

7274
create(rule: Rule) {

0 commit comments

Comments
 (0)