UNPKG

strapi-pfapi

Version:

a strapi plugin library uses local and redis caches to achieve single digit milliseconds on average api response time.

80 lines (67 loc) 2.58 kB
'use strict'; const { v4: uuidv4 } = require('uuid'); const get_config = require('../app/get-config'); const logging = require('../app/logging'); /** * redis pub sub with mechanism to exclude message from self */ class RedisPubsub { constructor(redis_cache) { if (!redis_cache) { throw new Error('missing required redis_cache'); } this.redis_cache = redis_cache; this.uuid = uuidv4(); this.config = get_config('RedisPubsub'); } async start() { this.pubsub_client = await this.on_pubsub(this.config.channel_name, async (event) => { const json = JSON.parse(event); if (this.config.exclude_self && json.from === this.uuid) return; await this.on_receive(json.message, json.from); }); } async publish(message) { const event = {from: this.uuid, message}; const client = await this.redis_cache.get_client(); return await client.publish(this.config.channel_name, JSON.stringify(event)); } async on_receive(message, from) { //console.log(message, from); } async stop() { if (!this.pubsub_client) return; await this.turnoff_pubsub(this.pubsub_client, this.config.channel_name); await this.redis_cache.close(this.pubsub_client); this.pubsub = null; } // support functions async on_pubsub(channel_name, on_event) { const subscribe_client = await this.redis_cache.get_client(async (new_client) => { try { const subscribe_result = await new_client.subscribe(channel_name); if (subscribe_result !== 1) { logging.error('on_pubsub, failed to subscribe'); await this.close(subscribe_client); return; } const id = await this.redis_cache.get_client_id(new_client); new_client.on('message', async (channel, data) => { const current_id = await this.redis_cache.get_client_id(new_client); if (current_id !== id) { await new_client.unsubscribe(channel); return; } await on_event(data); }); } catch(err) { logging.error(err); } }); return subscribe_client; } async turnoff_pubsub(subscribe_client, channel) { await subscribe_client.unsubscribe(channel); } } module.exports = RedisPubsub;