UNPKG

@opengis/fastify-table

Version:

core-plugins

113 lines (112 loc) 3.88 kB
const keyCacheSubscribe = "emit_cache"; const listenter = {}; // callback send message listener const promise = {}; // promise await for subscribe const resolve = {}; // resolve const publish = {}; // publish import config from "../../../../../config.js"; import getRedis from "../../../../plugins/redis/funcs/getRedis.js"; // getRedisPublisher function getRedisPublisher() { const rst = getRedis({ name: "rst", ...(config.redis || {}), }); const subscriber = getRedis({ name: "sub", ...(config.redis || {}), }); subscriber.unsubscribe(keyCacheSubscribe); subscriber.subscribe(keyCacheSubscribe, () => { }); subscriber.on("message", async (channel, text) => { const [code, msg] = text.split("|||"); if (msg === "finish" && resolve[code]) { resolve[code](); resolve[code] = null; } listenter[code].forEach((cb1, i) => { cb1(`${msg} - ${i}`); }); }); return rst; } // native publisher function getPublisher() { const rst = { publish(key, text) { const [code, msg] = text.split("|||"); listenter[code]?.forEach((cb1, i) => { cb1?.(`${msg} - ${i}`); }); }, }; return rst; } // !!! work non cluster mode for cluster subscribe redis export default async function subscribe(code, cb, reload) { try { const rclient = getRedis(); const { isRedis, timeout = 150 } = config?.redis?.pubsub || {}; // test! const publisher = isRedis ? getRedisPublisher() : getPublisher(); const keyCacheCode = `${keyCacheSubscribe}:${code}`; // check code is run const isNotRun = await rclient.setnx(keyCacheCode, 1); const ttl = await rclient.ttl(keyCacheCode); // if Run if (!isNotRun && !reload && ttl > 0) { // add listener cb(`==== run as slave ttl: ${ttl}==== `); const alldata = await rclient.lrange(keyCacheCode + ":list", 0, -1); alldata.forEach((el) => { cb(el); }); // for redis if (!listenter[code]) { listenter[code] = []; promise[code] = new Promise((rsv) => { resolve[code] = rsv; }); } // check master finish const interval = setInterval(async () => { const ttl1 = await rclient.ttl(keyCacheCode); if (ttl1 < 0) { clearInterval(interval); cb(`finish master timeout ${timeout}`, 1); } }, 5000); listenter[code].push(cb); return promise[code]; } await rclient.expire(keyCacheCode, timeout); // if not run // create return promise promise[code] = new Promise((rsv) => { resolve[code] = rsv; }); listenter[code] = [cb]; // listenter[code].push(cb); // create publish function publish[code] = (msg) => { rclient.rpush(keyCacheCode + ":list", msg); rclient.expire(keyCacheCode, timeout); // send message to all listener publisher.publish(keyCacheSubscribe, `${code}|||${msg}`); // redis // finish and clear if (msg === "finish") { // clear code to run again rclient.del(keyCacheCode); rclient.del(keyCacheCode + ":list"); // resolve promise resolve[code](); // clear resolve[code] = null; promise[code] = null; listenter[code] = []; } }; return publish[code]; } catch (err) { console.error(err.toString()); } }