envio
Version:
A latency and sync speed optimized, developer friendly blockchain data indexer.
118 lines (107 loc) • 3.64 kB
JavaScript
// Generated by ReScript, PLEASE EDIT WITH CARE
;
var Utils = require("./Utils.res.js");
var JsSdsl = require("js-sdsl");
var Belt_Option = require("rescript/lib/js/belt_Option.js");
var Caml_option = require("rescript/lib/js/caml_option.js");
var Caml_exceptions = require("rescript/lib/js/caml_exceptions.js");
var Caml_js_exceptions = require("rescript/lib/js/caml_js_exceptions.js");
var LoaderTimeout = /* @__PURE__ */Caml_exceptions.create("LazyLoader.LoaderTimeout");
function make(loaderFn, onError, cacheSizeOpt, loaderPoolSizeOpt, retryDelayMillisOpt, timeoutMillisOpt) {
var cacheSize = cacheSizeOpt !== undefined ? cacheSizeOpt : 10000;
var loaderPoolSize = loaderPoolSizeOpt !== undefined ? loaderPoolSizeOpt : 10;
var retryDelayMillis = retryDelayMillisOpt !== undefined ? retryDelayMillisOpt : 5000;
var 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(function () {
return Promise.reject({
RE_EXN_ID: LoaderTimeout,
_1: "Query took longer than " + String(timeoutMillis / 1000 | 0) + " seconds"
});
});
}
async function loadNext(am, k) {
am.inProgress.add(k);
var awaitTaskPromiseAndLoadNextWithTimeout = async function () {
var val = await Promise.race([
am.loaderFn(k),
timeoutAfter(am._timeoutMillis)
]);
Belt_Option.forEach(am.resolvers.get(k), (function (r) {
am.resolvers.delete(k);
r(val);
}));
am.inProgress.delete(k);
var loadedKeysNumber = am.loadedKeys.push(k);
if (loadedKeysNumber > am._cacheSize) {
var old = am.loadedKeys.pop();
if (old !== undefined) {
am.externalPromises.delete(Caml_option.valFromOption(old));
}
}
var next = am.loaderQueue.pop();
if (next !== undefined) {
return await loadNext(am, Caml_option.valFromOption(next));
}
};
var tmp;
var exit = 0;
var val;
try {
val = await awaitTaskPromiseAndLoadNextWithTimeout();
exit = 1;
}
catch (raw_err){
var err = Caml_js_exceptions.internalToOCamlException(raw_err);
var 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) {
var x = am.externalPromises.get(k);
if (x !== undefined) {
return Caml_option.valFromOption(x);
}
var promise = new Promise((function (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;
}
exports.LoaderTimeout = LoaderTimeout;
exports.make = make;
exports.deleteKey = deleteKey;
exports.timeoutAfter = timeoutAfter;
exports.loadNext = loadNext;
exports.get = get;
/* Utils Not a pure module */