Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature process polling #2480

Merged
merged 25 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
78d0bdd
104938 Implementation and tests (WIP)
Aug 18, 2023
c4d5777
ProcessDataService.notifyOnCompletion tests (WIP)
Aug 24, 2023
bd66487
104938 Add flush to process polling tests
Aug 25, 2023
3be90eb
rewrite notifyOnCompletion as autoRefreshUntilCompletion, fix Process…
artlowel Aug 29, 2023
a59776d
Failed attempt at fixing process-detail.component.spec.ts tests
Sep 1, 2023
53b0af1
104938 Fix ProcessDetailComponent tests
Sep 1, 2023
9b5001e
104938 Cleanup
Sep 7, 2023
8175a9d
Merge remote-tracking branch 'dspace/main' into feature-process_polling
Sep 7, 2023
11e98f7
Fix lint issue.
Sep 7, 2023
6b0f2e7
108915: Refactored code to use followLinks to retrieve the files of a…
alexandrevryghem Nov 30, 2023
e339b46
108915: Added the missing Filetypes followLink to Process
alexandrevryghem Nov 30, 2023
24eb5b4
108915: Always invalidate all followLinks when invalidating linked ca…
alexandrevryghem Dec 8, 2023
5400981
108915: Added tests proving that the addDependency is called on all t…
alexandrevryghem Dec 19, 2023
f35eab3
Merge branch 'feature-process_polling-7.6' into feature-process_polling
alexandrevryghem Dec 22, 2023
d37cd18
Merge remote-tracking branch 'upstream/main' into feature-process_pol…
alexandrevryghem Dec 22, 2023
9e31f73
108915: Fixed issue where the observable would emit itself again even…
alexandrevryghem Jan 5, 2024
c91b99f
108915: Fixed delete process error on ProcessDetailComponent
alexandrevryghem Jan 5, 2024
86d3883
Merge branch 'feature-process_polling-7.6' into feature-process_polling
alexandrevryghem Jan 8, 2024
359d452
Merge remote-tracking branch 'upstream/main' into feature-process_pol…
alexandrevryghem Jan 8, 2024
252b367
108915: Fixed issue that redirected you to 404 page when deleting the…
alexandrevryghem Feb 8, 2024
ecb20bb
108915: Fixed Proxy Timout error when retrieving a non-existing process
alexandrevryghem Feb 8, 2024
110633c
Merge branch 'feature-process_polling-7.6' into feature-process_polling
alexandrevryghem Feb 8, 2024
21cc311
Merge remote-tracking branch 'upstream/main' into feature-process_pol…
alexandrevryghem Feb 13, 2024
8ddc621
108915: Prevent self links & unresolved followLinks to be added as de…
alexandrevryghem Feb 19, 2024
049fbb8
Merge branch 'feature-process_polling-7.6' into feature-process_polling
alexandrevryghem Feb 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ describe('CollectionSourceControlsComponent', () => {
invoke: createSuccessfulRemoteDataObject$(process),
});
processDataService = jasmine.createSpyObj('processDataService', {
findById: createSuccessfulRemoteDataObject$(process),
autoRefreshUntilCompletion: createSuccessfulRemoteDataObject$(process),
});
bitstreamService = jasmine.createSpyObj('bitstreamService', {
findByHref: createSuccessfulRemoteDataObject$(bitstream),
Expand Down Expand Up @@ -137,7 +137,7 @@ describe('CollectionSourceControlsComponent', () => {
{name: '-i', value: new ContentSourceSetSerializer().Serialize(contentSource.oaiSetId)},
], []);

expect(processDataService.findById).toHaveBeenCalledWith(process.processId, false);
expect(processDataService.autoRefreshUntilCompletion).toHaveBeenCalledWith(process.processId);
expect(bitstreamService.findByHref).toHaveBeenCalledWith(process._links.output.href);
expect(notificationsService.info).toHaveBeenCalledWith(jasmine.anything() as any, 'Script text');
});
Expand All @@ -151,7 +151,7 @@ describe('CollectionSourceControlsComponent', () => {
{name: '-r', value: null},
{name: '-c', value: collection.uuid},
], []);
expect(processDataService.findById).toHaveBeenCalledWith(process.processId, false);
expect(processDataService.autoRefreshUntilCompletion).toHaveBeenCalledWith(process.processId);
expect(notificationsService.success).toHaveBeenCalled();
});
});
Expand All @@ -164,7 +164,7 @@ describe('CollectionSourceControlsComponent', () => {
{name: '-o', value: null},
{name: '-c', value: collection.uuid},
], []);
expect(processDataService.findById).toHaveBeenCalledWith(process.processId, false);
expect(processDataService.autoRefreshUntilCompletion).toHaveBeenCalledWith(process.processId);
expect(notificationsService.success).toHaveBeenCalled();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
import { ContentSource } from '../../../../core/shared/content-source.model';
import { ProcessDataService } from '../../../../core/data/processes/process-data.service';
import {
getAllCompletedRemoteData,
getAllSucceededRemoteDataPayload,
getFirstCompletedRemoteData,
getFirstSucceededRemoteDataPayload
} from '../../../../core/shared/operators';
import { filter, map, switchMap, tap } from 'rxjs/operators';
import { hasValue, hasValueOperator } from '../../../../shared/empty.util';
import { hasValue } from '../../../../shared/empty.util';
import { ProcessStatus } from '../../../../process-page/processes/process-status.model';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { RequestService } from '../../../../core/data/request.service';
Expand Down Expand Up @@ -95,36 +94,25 @@
}),
// filter out responses that aren't successful since the pinging of the process only needs to happen when the invocation was successful.
filter((rd) => rd.hasSucceeded && hasValue(rd.payload)),
switchMap((rd) => this.processDataService.findById(rd.payload.processId, false)),
getAllCompletedRemoteData(),
filter((rd) => !rd.isStale && (rd.hasSucceeded || rd.hasFailed)),
map((rd) => rd.payload),
hasValueOperator(),
switchMap((rd) => this.processDataService.autoRefreshUntilCompletion(rd.payload.processId)),
map((rd) => rd.payload)
).subscribe((process: Process) => {
if (process.processStatus.toString() !== ProcessStatus[ProcessStatus.COMPLETED].toString() &&
process.processStatus.toString() !== ProcessStatus[ProcessStatus.FAILED].toString()) {
// Ping the current process state every 5s
setTimeout(() => {
this.requestService.setStaleByHrefSubstring(process._links.self.href);
}, 5000);
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
this.notificationsService.error(this.translateService.get('collection.source.controls.test.failed'));
this.testConfigRunning$.next(false);
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
this.bitstreamService.findByHref(process._links.output.href).pipe(getFirstSucceededRemoteDataPayload()).subscribe((bitstream) => {
this.httpClient.get(bitstream._links.content.href, {responseType: 'text'}).subscribe((data: any) => {
const output = data.replaceAll(new RegExp('.*\\@(.*)', 'g'), '$1')
.replaceAll('The script has started', '')
.replaceAll('The script has completed', '');
this.notificationsService.info(this.translateService.get('collection.source.controls.test.completed'), output);
});
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
this.notificationsService.error(this.translateService.get('collection.source.controls.test.failed'));
this.testConfigRunning$.next(false);

Check warning on line 102 in src/app/collection-page/edit-collection-page/collection-source/collection-source-controls/collection-source-controls.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/collection-page/edit-collection-page/collection-source/collection-source-controls/collection-source-controls.component.ts#L101-L102

Added lines #L101 - L102 were not covered by tests
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
this.bitstreamService.findByHref(process._links.output.href).pipe(getFirstSucceededRemoteDataPayload()).subscribe((bitstream) => {
this.httpClient.get(bitstream._links.content.href, {responseType: 'text'}).subscribe((data: any) => {
const output = data.replaceAll(new RegExp('.*\\@(.*)', 'g'), '$1')
.replaceAll('The script has started', '')
.replaceAll('The script has completed', '');
this.notificationsService.info(this.translateService.get('collection.source.controls.test.completed'), output);
});
this.testConfigRunning$.next(false);
}
});
this.testConfigRunning$.next(false);
}
));
}));
}

/**
Expand All @@ -147,31 +135,19 @@
}
}),
filter((rd) => rd.hasSucceeded && hasValue(rd.payload)),
switchMap((rd) => this.processDataService.findById(rd.payload.processId, false)),
getAllCompletedRemoteData(),
filter((rd) => !rd.isStale && (rd.hasSucceeded || rd.hasFailed)),
map((rd) => rd.payload),
hasValueOperator(),
switchMap((rd) => this.processDataService.autoRefreshUntilCompletion(rd.payload.processId)),
map((rd) => rd.payload)
).subscribe((process) => {
if (process.processStatus.toString() !== ProcessStatus[ProcessStatus.COMPLETED].toString() &&
process.processStatus.toString() !== ProcessStatus[ProcessStatus.FAILED].toString()) {
// Ping the current process state every 5s
setTimeout(() => {
this.requestService.setStaleByHrefSubstring(process._links.self.href);
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
}, 5000);
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
this.notificationsService.error(this.translateService.get('collection.source.controls.import.failed'));
this.importRunning$.next(false);
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
this.notificationsService.success(this.translateService.get('collection.source.controls.import.completed'));
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
this.importRunning$.next(false);
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
this.notificationsService.error(this.translateService.get('collection.source.controls.import.failed'));
this.importRunning$.next(false);

Check warning on line 143 in src/app/collection-page/edit-collection-page/collection-source/collection-source-controls/collection-source-controls.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/collection-page/edit-collection-page/collection-source/collection-source-controls/collection-source-controls.component.ts#L142-L143

Added lines #L142 - L143 were not covered by tests
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
this.notificationsService.success(this.translateService.get('collection.source.controls.import.completed'));
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
this.importRunning$.next(false);
}
));
}));
}

/**
Expand All @@ -194,31 +170,19 @@
}
}),
filter((rd) => rd.hasSucceeded && hasValue(rd.payload)),
switchMap((rd) => this.processDataService.findById(rd.payload.processId, false)),
getAllCompletedRemoteData(),
filter((rd) => !rd.isStale && (rd.hasSucceeded || rd.hasFailed)),
map((rd) => rd.payload),
hasValueOperator(),
switchMap((rd) => this.processDataService.autoRefreshUntilCompletion(rd.payload.processId)),
map((rd) => rd.payload)
).subscribe((process) => {
if (process.processStatus.toString() !== ProcessStatus[ProcessStatus.COMPLETED].toString() &&
process.processStatus.toString() !== ProcessStatus[ProcessStatus.FAILED].toString()) {
// Ping the current process state every 5s
setTimeout(() => {
this.requestService.setStaleByHrefSubstring(process._links.self.href);
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
}, 5000);
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
this.notificationsService.error(this.translateService.get('collection.source.controls.reset.failed'));
this.reImportRunning$.next(false);
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
this.notificationsService.success(this.translateService.get('collection.source.controls.reset.completed'));
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
this.reImportRunning$.next(false);
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
this.notificationsService.error(this.translateService.get('collection.source.controls.reset.failed'));
this.reImportRunning$.next(false);

Check warning on line 178 in src/app/collection-page/edit-collection-page/collection-source/collection-source-controls/collection-source-controls.component.ts

View check run for this annotation

Codecov / codecov/patch

src/app/collection-page/edit-collection-page/collection-source/collection-source-controls/collection-source-controls.component.ts#L177-L178

Added lines #L177 - L178 were not covered by tests
}
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
this.notificationsService.success(this.translateService.get('collection.source.controls.reset.completed'));
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
this.reImportRunning$.next(false);
}
));
}));
}

ngOnDestroy(): void {
Expand Down
5 changes: 3 additions & 2 deletions src/app/core/cache/builders/remote-data-build.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,13 @@ export class RemoteDataBuildService {
return isStale(r2.state) ? r1 : r2;
}
}),
distinctUntilKeyChanged('lastUpdated')
);

const payload$ = this.buildPayload<T>(requestEntry$, href$, ...linksToFollow);

return this.toRemoteDataObservable<T>(requestEntry$, payload$);
return this.toRemoteDataObservable<T>(requestEntry$, payload$).pipe(
distinctUntilKeyChanged('lastUpdated'),
);
}

/**
Expand Down
Loading
Loading