const run = async (operation, name, timeoutDurationInMs, task) => { log().info({operation, name, timeoutDurationInMs}, `Will try to run operation "${operation}" on "${name}" (timeout: ${timeoutDurationInMs} ms)`) const {start, end} = await store().save(operation, name, timeoutDurationInMs) const remainingTimeInMs = moment(start).add(timeoutDurationInMs, 'milliseconds').diff(moment(new Date())) try { return await pTimeout(task(), remainingTimeInMs, () => { throw Boom.gatewayTimeout(`Operation '${operation}' Timeout: the operation started ${moment(start).fromNow()} did not finish in the given '${timeoutDurationInMs}' ms time it had to ( it should have finished well before ${moment(end).fromNow()}). You are likely to have to either change this timeout because it was not enough, or make some manual operations in your Elasticsearch Cluster`) }) } finally { store().delete(operation, name) } }