Skip to content
Snippets Groups Projects
Commit 6066e3ae authored by David Sehnal's avatar David Sehnal
Browse files

retryIf

parent c20577b3
Branches
No related tags found
No related merge requests found
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
export async function retryIf<T>(promiseProvider: () => Promise<T>, params: {
retryThenIf?: (result: T) => boolean,
retryCatchIf?: (error: any) => boolean,
retryCount: number
}) {
let count = 0;
while (count <= params.retryCount) {
try {
const result = await promiseProvider();
if (params.retryThenIf && params.retryThenIf(result)) {
count++;
continue;
}
return result;
} catch (e) {
if (!params.retryCatchIf || params.retryCatchIf(e)) {
count++;
continue;
}
throw e;
}
}
throw new Error('Maximum retry count exceeded.');
}
\ No newline at end of file
...@@ -4,12 +4,12 @@ ...@@ -4,12 +4,12 @@
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
*/ */
import { ResidueIndex, ModelPropertyDescriptor, Model, Structure, Unit, StructureElement } from 'mol-model/structure';
import fetch from 'node-fetch';
import { CifWriter } from 'mol-io/writer/cif';
import CifField = CifWriter.Field;
import { Segmentation } from 'mol-data/int'; import { Segmentation } from 'mol-data/int';
import { CifWriter } from 'mol-io/writer/cif';
import { Model, ModelPropertyDescriptor, ResidueIndex, Structure, StructureElement, Unit } from 'mol-model/structure';
import { residueIdFields } from 'mol-model/structure/export/categories/atom_site'; import { residueIdFields } from 'mol-model/structure/export/categories/atom_site';
import { fetchRetry } from '../utils/fetch-retry';
import CifField = CifWriter.Field;
type IssueMap = Map<ResidueIndex, string[]> type IssueMap = Map<ResidueIndex, string[]>
...@@ -99,7 +99,7 @@ export namespace StructureQualityReport { ...@@ -99,7 +99,7 @@ export namespace StructureQualityReport {
if (model.customProperties.has(Descriptor)) return true; if (model.customProperties.has(Descriptor)) return true;
const id = model.label.toLowerCase(); const id = model.label.toLowerCase();
const rawData = await fetch(`https://www.ebi.ac.uk/pdbe/api/validation/residuewise_outlier_summary/entry/${model.label.toLowerCase()}`, { timeout: 1500 }); const rawData = await fetchRetry(`https://www.ebi.ac.uk/pdbe/api/validation/residuewise_outlier_summary/entry/${model.label.toLowerCase()}`, 1500, 5);
const json = await rawData.json(); const json = await rawData.json();
const data = json[id]; const data = json[id];
if (!data) return false; if (!data) return false;
......
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import fetch from 'node-fetch';
import { retryIf } from 'mol-util/retry-if';
const RETRIABLE_NETWORK_ERRORS = [
'ECONNRESET', 'ENOTFOUND', 'ESOCKETTIMEDOUT', 'ETIMEDOUT',
'ECONNREFUSED', 'EHOSTUNREACH', 'EPIPE', 'EAI_AGAIN'
];
function isRetriableNetworkError(error: any) {
return error && RETRIABLE_NETWORK_ERRORS.includes(error.code);
}
export async function fetchRetry(url: string, timeout: number, retryCount: number) {
const result = await retryIf(() => fetch(url, { timeout }), {
retryThenIf: r => r.status >= 500 && r.status < 600,
// TODO test retryCatchIf
retryCatchIf: e => isRetriableNetworkError(e),
retryCount
});
if (result.status >= 200 && result.status < 300) return result;
throw new Error(result.statusText);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment