import CategoryService, { CategoryRequest } from "../services/category.service"; import { RedisClient } from "../services/redis.service"; import { Consumer } from "../utils/consumerSetQueue"; import logger from "../utils/logger"; import MetricService, { BucketSet, EndFunction } from "../services/metric.service"; import { ICategoryProvider, CategoryProviderValue } from "./categoryProvider"; import CategoryProviderMap from "./categoryProviderMap"; export default class CategoryRedisWriterConsumer implements Consumer { private redisClient: RedisClient; private categoryService: CategoryService; private metricService: MetricService; private CATEGORY_WRITE_SECTION: string = "cat_write"; constructor(redisClient: RedisClient, categoryService: CategoryService) { this.redisClient = redisClient; this.categoryService = categoryService; this.metricService = MetricService.getInstance(); this.metricService.addSection( this.CATEGORY_WRITE_SECTION, ["status", "provider", "category_type"], BucketSet.zeroTo600ms ); } async consume(queueElement: CategoryRequest): Promise { const end: EndFunction = this.metricService.startSection(this.CATEGORY_WRITE_SECTION); const providerType = queueElement.provider; const provider: ICategoryProvider = CategoryProviderMap[providerType]; const key: string = this.categoryService.encodeRedisKey(queueElement, provider); if (await this.categoryService.isKeyStale(key, this.redisClient)) { const lock = await this.redisClient.getRedisLock(key, 10 * 60 * 1000); if (lock != null) { try { const isStale: boolean = await this.categoryService.isKeyStale(key, this.redisClient); if (isStale) { const value: CategoryProviderValue = await provider.getCategories(queueElement); await this.redisClient.setPX(key, value.encodedValue, value.ttl); end(true, { status: "updated", provider: providerType, category_type: queueElement.device ? "device" : "publisher", }); } else { end(true, { status: "not_changed" }); } } catch (error: any) { end(false, { status: "error" }); logger.error(error); } finally { await lock.unlock(); } } else { end(false, { status: "locked" }); } } } close(): void { this.redisClient.disconnect(); } }