From 23ebc4f8eab30dd58b3198402d6d65fe81558bed Mon Sep 17 00:00:00 2001 From: rjawesome Date: Mon, 24 Jun 2024 15:11:43 -0700 Subject: [PATCH] allow queries to be aborted --- package.json | 2 +- src/attrs.ts | 17 ++++++++++------- src/index.ts | 8 ++++---- src/sri.ts | 11 ++++++----- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 7c5b2d0..dd60bb8 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "@commitlint/cli": "^17.8.1", "@commitlint/config-conventional": "^11.0.0", "axios-retry": "^3.8.0", - "axios": "^0.21.4", + "axios": "^1.7.2", "biolink-model": "workspace:../biolink-model", "debug": "^4.3.4", "husky": "^8.0.3", diff --git a/src/attrs.ts b/src/attrs.ts index 822318a..575cd7a 100644 --- a/src/attrs.ts +++ b/src/attrs.ts @@ -108,6 +108,7 @@ function buildOneQuery( prefix: string, inputs: string[], semanticType: string, + abortSignal?: AbortSignal ): Promise { const idReturnFields = getReturnFields(metadata.mapping); let attrReturnFields = ''; @@ -135,8 +136,9 @@ function buildOneQuery( 'content-type': 'application/json', 'User-Agent': userAgent, }, + signal: abortSignal, }) - .then((response) => getDBIDs(prefix, semanticType, response.data)) + .then((response) => getDBIDs(prefix, semanticType, response.data as any)) .catch(() => undefined); } @@ -145,13 +147,14 @@ function buildQueries( prefix: string, inputs: string[], semanticType: string, + abortSignal?: AbortSignal ): Promise[] { if (inputs.length > MAX_BIOTHINGS_INPUT_SIZE) { return _.chunk(inputs, MAX_BIOTHINGS_INPUT_SIZE).map((batch) => - buildOneQuery(metadata, prefix, batch, semanticType), + buildOneQuery(metadata, prefix, batch, semanticType, abortSignal), ); } else { - return [buildOneQuery(metadata, prefix, inputs, semanticType)]; + return [buildOneQuery(metadata, prefix, inputs, semanticType, abortSignal)]; } } @@ -159,10 +162,10 @@ function getAPIMetaData(semanticType: string) { return APIMETA[semanticType]; } -function build(semanticType: string, curies: string[]): Promise[] { +function build(semanticType: string, curies: string[], abortSignal?: AbortSignal): Promise[] { const grped = groupCuriesByPrefix(curies); return Object.keys(grped).reduce((prev: Promise[], current) => { - prev = [...prev, ...buildQueries(getAPIMetaData(semanticType), current, grped[current], semanticType)]; + prev = [...prev, ...buildQueries(getAPIMetaData(semanticType), current, grped[current], semanticType, abortSignal)]; return prev; }, []); } @@ -181,7 +184,7 @@ function getSupportedType(category: string): string { return ''; } -export async function _getAttributes(idsByType: object): Promise { +export async function _getAttributes(idsByType: object, abortSignal?: AbortSignal): Promise { debug(`Adding attributes of ${JSON.stringify(idsByType)}`); let promises: Promise[] = []; for (const type in idsByType) { @@ -190,7 +193,7 @@ export async function _getAttributes(idsByType: object): Promise { if (ids) { if (supportedType) { debug(`Processing attributes of: ${JSON.stringify(type)}`); - promises = [...promises, ...build(supportedType, ids)]; + promises = [...promises, ...build(supportedType, ids, abortSignal)]; } else { debug(`Cannot get attributes of type: ${JSON.stringify(type)}`); } diff --git a/src/index.ts b/src/index.ts index 8cd5a4a..ba32ee0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -34,12 +34,12 @@ export class Resolver implements IResolver { } } -export async function resolveSRI(userInput: ResolverInput): Promise { - return await _resolveSRI(userInput); +export async function resolveSRI(userInput: ResolverInput, abortSignal?: AbortSignal): Promise { + return await _resolveSRI(userInput, abortSignal); } -export async function getAttributes(idsByType: object): Promise { - return await _getAttributes(idsByType); +export async function getAttributes(idsByType: object, abortSignal?: AbortSignal): Promise { + return await _getAttributes(idsByType, abortSignal); } export const METADATA = APIMETA; diff --git a/src/sri.ts b/src/sri.ts index 043f23a..40fdf82 100644 --- a/src/sri.ts +++ b/src/sri.ts @@ -29,7 +29,7 @@ function combineInputs(userInput: ResolverInput): string[] { * input: array of curies * handles querying and batching of inputs */ -async function query(api_input: string[]) { +async function query(api_input: string[], abortSignal?: AbortSignal) { const url = { dev: 'https://nodenormalization-sri.renci.org/get_normalized_nodes', ci: 'https://nodenorm.ci.transltr.io/get_normalized_nodes', @@ -47,7 +47,7 @@ async function query(api_input: string[]) { return axios.post( url, { curies: input, conflate: true, drug_chemical_conflate: true }, - { headers: { 'User-Agent': userAgent } }, + { headers: { 'User-Agent': userAgent }, signal: abortSignal }, ); }); //convert res array into single object with all curies @@ -57,7 +57,8 @@ async function query(api_input: string[]) { }); return Object.assign({}, ...res); } catch (err) { - throw new SRINodeNormFailure(`SRI resolver failed: ${err.message}`); + // throw new SRINodeNormFailure(`SRI resolver failed: ${err.message}`); + return Object.fromEntries(api_input.map((curie) => [curie, null])); } } @@ -135,10 +136,10 @@ function mapInputSemanticTypes(originalInput: ResolverInput, result: SRIResolver return result; } -export async function _resolveSRI(userInput: ResolverInput): Promise { +export async function _resolveSRI(userInput: ResolverInput, abortSignal?: AbortSignal): Promise { const uniqueInputIDs = combineInputs(userInput); - let queryResults = await query(uniqueInputIDs); + let queryResults = await query(uniqueInputIDs, abortSignal); queryResults = transformResults(queryResults);