diff --git a/platform/core/package.json b/platform/core/package.json index ced3f230f..605c82ab4 100644 --- a/platform/core/package.json +++ b/platform/core/package.json @@ -46,6 +46,7 @@ "lodash.clonedeep": "^4.5.0", "lodash.merge": "^4.6.1", "mousetrap": "^1.6.3", + "retry": "^0.12.0", "validate.js": "^0.12.0" } } diff --git a/platform/core/src/studies/services/wado/retrieveMetadataLoaderAsync.js b/platform/core/src/studies/services/wado/retrieveMetadataLoaderAsync.js index 81585772b..a008c5154 100644 --- a/platform/core/src/studies/services/wado/retrieveMetadataLoaderAsync.js +++ b/platform/core/src/studies/services/wado/retrieveMetadataLoaderAsync.js @@ -1,5 +1,6 @@ import { api } from 'dicomweb-client'; import dcmjs from 'dcmjs'; +import retry, { operation } from 'retry'; import DICOMWeb from '../../../DICOMWeb/'; import RetrieveMetadataLoader from './retrieveMetadataLoader'; import { sortStudySeries, sortingCriteria } from '../../sortStudy'; @@ -76,6 +77,42 @@ export default class RetrieveMetadataLoaderAsync extends RetrieveMetadataLoader url: server.qidoRoot, headers: DICOMWeb.getAuthorizationHeader(server), errorInterceptor: errorHandler.getHTTPErrorHandler(), + enhancers: [ + (request, metadata) => { + function faultTolerantRequestSend(...args) { + const operation = retry.operation({ + retries: 10, + }); + /** + * retries: 5, + * factor: 3, + * minTimeout: 1 * 1000, + * maxTimeout: 60 * 1000, + * randomize: true + */ + + operation.attempt(function(currentAttempt) { + const originalOnReadyStateChange = request.onreadystatechange; + + request.onreadystatechange = function() { + originalOnReadyStateChange.call(request); + if (request.status === 429 || request.status >= 500) { + operation.retry(new Error('Attempt failed!')); + } + }; + + console.debug(`${metadata.url} (attempt: ${currentAttempt})`); + request.open(metadata.method, metadata.url, true); + originalRequestSend.call(request, ...args); + }); + } + + const originalRequestSend = request.send; + request.send = faultTolerantRequestSend; + + return request; + }, + ], }); this.client = client; diff --git a/yarn.lock b/yarn.lock index 7d49192bb..db9b980d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1247,13 +1247,34 @@ pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime@7.1.2", "@babel/runtime@7.5.5", "@babel/runtime@7.6.0", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.6": +"@babel/runtime@7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.2.tgz#81c89935f4647706fc54541145e6b4ecfef4b8e3" + integrity sha512-Y3SCjmhSupzFB6wcv1KmmFucH6gDVnI30WjOcicV10ju0cZjak3Jcs67YLIXBrmZYw1xCrVeJPbycFwrqNyxpg== + dependencies: + regenerator-runtime "^0.12.0" + +"@babel/runtime@7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.0.tgz#4fc1d642a9fd0299754e8b5de62c631cf5568205" + integrity sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ== + dependencies: + regenerator-runtime "^0.13.2" + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== dependencies: regenerator-runtime "^0.13.2" +"@babel/runtime@^7.6.0", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.6": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" + integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6" @@ -16523,6 +16544,11 @@ regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== + regenerator-runtime@^0.13.1, regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4: version "0.13.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"