Commit db034ed5 authored by Florent POITTEVIN's avatar Florent POITTEVIN
Browse files

feat: 1612 polling incremental time with limit to stop polling

parent 1aa20cb8
......@@ -3725,6 +3725,11 @@
"integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
"dev": true
},
"backoff-rxjs": {
"version": "6.5.7",
"resolved": "https://nexus.unige.ch/repository/npm-all/backoff-rxjs/-/backoff-rxjs-6.5.7.tgz",
"integrity": "sha512-j3pEcM5ivIxZhkZ+CcF8LVb5/jORNT4HCEnzavFfBkXSEJfx/WMtq79NKKp8Z0IDThgXxnlvzf41Gvajb4C2NQ=="
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://nexus.unige.ch/repository/npm-all/balanced-match/-/balanced-match-1.0.0.tgz",
......
......@@ -295,6 +295,9 @@ export class DepositDetailEditRoutable extends SharedAbstractDetailEditRoutable<
private _createPollingListenerForFileReady(): void {
this.subscribe(PollingHelper.startPollingObs({
intervalRefreshInSecond: environment.refreshDepositSubmittedIntervalInSecond,
incremental: true,
maxIntervalInSecond: 60,
stopAfterMaxIntervalReached: true,
doBeforeFilter: () => {
const shouldContinuePollingBefore = this.shouldContinuePolling;
this.computedShouldContinuePolling();
......
......@@ -1029,6 +1029,8 @@ export class DepositState extends ResourceLogoState<DepositStateModel, Deposit>
return PollingHelper.startPollingObs({
intervalRefreshInSecond: 1,
incremental: true,
maxIntervalInSecond: 5,
continueUntil: () => !isReady,
actionToDo: () => {
const url = `${this._urlResource}/${depositId}/${ApiResourceNameEnum.DATAFILE}/${datafileId}`;
......
......@@ -141,12 +141,14 @@ export class OrderMyOrderDetailEditRoutable extends SharedAbstractDetailEditComm
];
private readonly INTERVAL_REFRESH_IN_SECOND: number = 5;
private readonly INTERVAL_MAX: number = 5;
ngOnInit(): void {
super.ngOnInit();
this.subscribe(PollingHelper.startPollingObs({
intervalRefreshInSecond: this.INTERVAL_REFRESH_IN_SECOND,
incremental: true,
continueUntil: () => isNullOrUndefined(this.current) || (this.current.status !== Enums.Order.StatusEnum.READY && this.current.status !== Enums.Order.StatusEnum.INERROR),
actionToDo: () => this._store.dispatch(ResourceActionHelper.getById(this._resourceNameSpace, this._resId, true)),
}));
......@@ -174,6 +176,7 @@ export class OrderMyOrderDetailEditRoutable extends SharedAbstractDetailEditComm
this.subscribe(PollingHelper.startPollingObs({
// Manage case when we are on the page that become ready
intervalRefreshInSecond: 1,
incremental: true,
filter: () => (this.current.status === Enums.Order.StatusEnum.READY || this.current.status === Enums.Order.StatusEnum.INERROR) && SessionStorageHelper.getListItem(SessionStorageEnum.newOrderAvailable)
.includes(this._resId),
actionToDo: () => {
......
......@@ -58,6 +58,7 @@ export class PreservationPlanningJobExecutionListContainer extends SharedAbstrac
columns: DataTableColumns<JobExecution>[];
paramMessage: { name: string } = {name: StringUtil.stringEmpty};
private readonly INTERVAL_REFRESH_IN_SECOND: number = 0.2;
private readonly MAX_INTERVAL_REFRESH_IN_SECOND: number = 2;
pollingToUpdateProgressBar: boolean = false;
private _resId: string;
......@@ -77,6 +78,8 @@ export class PreservationPlanningJobExecutionListContainer extends SharedAbstrac
this.subscribe(PollingHelper.startPollingObs({
intervalRefreshInSecond: this.INTERVAL_REFRESH_IN_SECOND,
incremental: true,
maxIntervalInSecond: this.MAX_INTERVAL_REFRESH_IN_SECOND,
filter: () => isTrue(this.pollingToUpdateProgressBar),
actionToDo: () => this.getAll(),
}));
......
......@@ -166,6 +166,7 @@ export class PreservationPlanningJobExecutionDetailRoutable extends SharedAbstra
this.subscribe(PollingHelper.startPollingObs({
intervalRefreshInSecond: 2,
incremental: true,
continueUntil: () => isNullOrUndefined(CompositionState.currentSnapshot(this._store, PreservationPlanningJobExecutionState)) || (CompositionState.currentSnapshot(this._store, PreservationPlanningJobExecutionState).status !== Enums.PreservationJob.ExecutionStatusEnum.IN_ERROR &&
CompositionState.currentSnapshot(this._store, PreservationPlanningJobExecutionState).status !== Enums.PreservationJob.ExecutionStatusEnum.COMPLETED),
actionToDo: () => this.refresh(),
......
import {environment} from "@environments/environment";
import {intervalBackoff} from "backoff-rxjs";
import {exponentialBackoffDelay} from "backoff-rxjs/utils";
import {
Observable,
timer,
......@@ -8,16 +11,51 @@ import {
takeWhile,
tap,
} from "rxjs/operators";
import {isUndefined} from "solidify-frontend";
import {
isFalse,
isNumberFinite,
isTrue,
isUndefined,
} from "solidify-frontend";
export class PollingHelper<Type> {
private static SECOND_TO_MILLISECOND: number = 1000;
static startPollingObs<Type>(config: PollingConfigInfo<Type>): Observable<Type> {
const intervalInMillisecond = config.intervalRefreshInSecond * 1000;
return timer(intervalInMillisecond, intervalInMillisecond).pipe(
const stopAfterMaxIntervalReached = isTrue(config.incremental) && isTrue(config.stopAfterMaxIntervalReached);
let maxIntervalReached = false;
const maxIntervalInSecond = isNumberFinite(config.maxIntervalInSecond) ? config.maxIntervalInSecond : environment.pollingMaxIntervalInSecond;
const intervalInMillisecond = config.intervalRefreshInSecond * this.SECOND_TO_MILLISECOND;
let observable = timer(intervalInMillisecond, intervalInMillisecond);
if (isTrue(config.incremental)) {
observable = intervalBackoff({
initialInterval: intervalInMillisecond,
maxInterval: maxIntervalInSecond * this.SECOND_TO_MILLISECOND,
backoffDelay: (iteration, initialInterval) => {
const interval = exponentialBackoffDelay(iteration, initialInterval);
if (isTrue(stopAfterMaxIntervalReached) && isFalse(maxIntervalReached)) {
maxIntervalReached = interval >= maxIntervalInSecond * this.SECOND_TO_MILLISECOND;
}
return interval;
},
}).pipe(
filter(() => {
const shouldContinue = isFalse(stopAfterMaxIntervalReached) || isFalse(maxIntervalReached);
return shouldContinue;
}),
);
}
return observable.pipe(
takeWhile(() => isUndefined(config.continueUntil) || config.continueUntil()),
tap(() => isUndefined(config.doBeforeFilter) || config.doBeforeFilter()),
filter(() => isUndefined(config.filter) || config.filter()),
map(() => config.actionToDo()),
tap(() => {
// if (isTrue(config.incremental)) {
// console.warn("INCREMENTE TIME: " + DateUtil.convertDateToTimeString(new Date()));
// }
}),
);
}
}
......@@ -28,4 +66,7 @@ export interface PollingConfigInfo<Type> {
continueUntil?: () => boolean | undefined;
filter?: () => boolean | undefined;
actionToDo: () => Type;
incremental?: boolean | undefined;
maxIntervalInSecond?: number | undefined;
stopAfterMaxIntervalReached?: boolean | undefined;
}
......@@ -94,6 +94,7 @@ export interface DlcmEnvironment extends DefaultSolidifyEnvironment {
refreshOrderAvailableIntervalInSecond: number;
refreshNotificationInboxAvailableIntervalInSecond: number;
refreshDepositSubmittedIntervalInSecond: number;
pollingMaxIntervalInSecond: number;
cdkDropListIdPrefix: string;
classInputIgnored: string;
......
......@@ -124,6 +124,8 @@ export const defaultEnvironment: DlcmEnvironment = {
validationErrorRequiredToTranslate: MARK_AS_TRANSLATABLE("validation.error.required"),
validationErrorInvalidToTranslate: MARK_AS_TRANSLATABLE("validation.error.invalid"),
pollingMaxIntervalInSecond: 60,
// Errors
httpErrorKeyToSkipInErrorHandler: [
ErrorBackendKeyEnum.UPLOAD_DUPLICATE_DATA_FILES,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment