UNPKG

envio

Version:

A latency and sync speed optimized, developer friendly blockchain data indexer.

113 lines (104 loc) 3.26 kB
// Generated by ReScript, PLEASE EDIT WITH CARE import * as Utils from "./Utils.res.mjs"; import * as JsSdsl from "js-sdsl"; import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js"; import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js"; let LoaderTimeout = /* @__PURE__ */Primitive_exceptions.create("LazyLoader.LoaderTimeout"); function make(loaderFn, onError, cacheSizeOpt, loaderPoolSizeOpt, retryDelayMillisOpt, timeoutMillisOpt) { let cacheSize = cacheSizeOpt !== undefined ? cacheSizeOpt : 10000; let loaderPoolSize = loaderPoolSizeOpt !== undefined ? loaderPoolSizeOpt : 10; let retryDelayMillis = retryDelayMillisOpt !== undefined ? retryDelayMillisOpt : 5000; let timeoutMillis = timeoutMillisOpt !== undefined ? timeoutMillisOpt : 300000; return { _cacheSize: cacheSize, _loaderPoolSize: loaderPoolSize, _retryDelayMillis: retryDelayMillis, _timeoutMillis: timeoutMillis, externalPromises: new Map(), resolvers: new Map(), inProgress: new Set(), loaderQueue: new JsSdsl.Queue(), loadedKeys: new JsSdsl.Queue(), loaderFn: loaderFn, onError: onError }; } function deleteKey(_obj, _k) { ((delete _obj[_k])); } function timeoutAfter(timeoutMillis) { return Utils.delay(timeoutMillis).then(() => Promise.reject({ RE_EXN_ID: LoaderTimeout, _1: `Query took longer than ` + (timeoutMillis / 1000 | 0).toString() + ` seconds` })); } async function loadNext(am, k) { am.inProgress.add(k); let awaitTaskPromiseAndLoadNextWithTimeout = async () => { let val = await Promise.race([ am.loaderFn(k), timeoutAfter(am._timeoutMillis) ]); Stdlib_Option.forEach(am.resolvers.get(k), r => { am.resolvers.delete(k); r(val); }); am.inProgress.delete(k); let loadedKeysNumber = am.loadedKeys.push(k); if (loadedKeysNumber > am._cacheSize) { let old = am.loadedKeys.pop(); if (old !== undefined) { am.externalPromises.delete(Primitive_option.valFromOption(old)); } } let next = am.loaderQueue.pop(); if (next !== undefined) { return await loadNext(am, Primitive_option.valFromOption(next)); } }; let tmp; let exit = 0; let val; try { val = await awaitTaskPromiseAndLoadNextWithTimeout(); exit = 1; } catch (raw_err) { let err = Primitive_exceptions.internalToException(raw_err); let onError = am.onError; if (onError !== undefined) { onError(am, err); } await Utils.delay(am._retryDelayMillis); tmp = awaitTaskPromiseAndLoadNextWithTimeout(); } if (exit === 1) { tmp = Promise.resolve(); } return await tmp; } function get(am, k) { let x = am.externalPromises.get(k); if (x !== undefined) { return x; } let promise = new Promise((resolve, param) => { am.resolvers.set(k, resolve); }); am.externalPromises.set(k, promise); if (am.inProgress.size < am._loaderPoolSize) { loadNext(am, k); } else { am.loaderQueue.push(k); } return promise; } export { LoaderTimeout, make, deleteKey, timeoutAfter, loadNext, get, } /* Utils Not a pure module */