import Debug from "debug" ; import { ServiceConfig } from "../../interfaces/ServiceConfig" ; import { Metrics } from "../metrics/Metrics" ; import { RedisClient } from "./RedisClient" ; import { YildizSingleSchema } from "../../interfaces/Yildiz" ; const debug = Debug ( "yildiz:lookupcache" ) ; export class LookupCache { private config : ServiceConfig ; private metrics : Metrics ; private redisClient : RedisClient ; private tosv ! : NodeJS . Timer | number ; constructor ( config , metrics , redisClient ) { this . config = config ; this . metrics = metrics ; this . redisClient = redisClient ; this . init ( ) ; } public init ( ) { const { sizeIntervalInSec = 5 } = this . config . lookupCache || { } ; debug ( `getting a dbsize job active running every ${ sizeIntervalInSec } sec` ) ; this . runJobSize ( sizeIntervalInSec ) ; } private runJobSize ( sizeIntervalInSec ) { this . tosv = setTimeout ( ( ) => { this . getSize ( ) . then ( ( size ) => { this . metrics . set ( "redis_dbsize" , size ) ; this . runJobSize ( sizeIntervalInSec ) ; } ) . catch ( ( error ) => { debug ( "getting size job failed." , error ) ; this . runJobSize ( sizeIntervalInSec ) ; } ) ; } , sizeIntervalInSec * 1000 ) ; } private async getSize ( ) { return await this . redisClient . getSize ( ) ; } public async classifyExistence ( keys ) { const start = Date . now ( ) ; let mExistence ; try { mExistence = await this . redisClient . mgetExistence ( keys ) ; } catch ( error ) { throw error ; } const cacheKeys = [ ] ; const nocacheKeys = [ ] ; if ( ! mExistence ) { return { cache : cacheKeys , nocache : keys , } ; } keys . map ( ( key , index ) => { if ( mExistence [ index ] ) { cacheKeys . push ( key ) ; } else { nocacheKeys . push ( key ) ; } } ) ; this . metrics . inc ( "redis_existence_rate" , keys . length ) ; this . metrics . set ( "lookup_classifyExistence" , ( Date . now ( ) - start ) ) ; return { cache : cacheKeys , nocache : nocacheKeys , } ; } public async classifyRightNode ( keys ) { const start = Date . now ( ) ; let mRightNode ; try { mRightNode = await this . redisClient . mgetRightNode ( keys ) ; } catch ( error ) { throw error ; } const cacheNodes = [ ] ; const nocacheKeys = [ ] ; if ( ! mRightNode ) { return { cache : cacheNodes , nocache : keys , } ; } keys . map ( ( key , index ) => { if ( mRightNode [ index ] ) { cacheNodes . push ( JSON . parse ( mRightNode [ index ] ) ) ; } else { nocacheKeys . push ( key ) ; } } ) ; this . metrics . inc ( "redis_rightnode_rate" , keys . length ) ; this . metrics . set ( "lookup_classifyRightNode" , ( Date . now ( ) - start ) ) ; return { cache : cacheNodes , nocache : nocacheKeys , } ; } public async setExistence ( identifiers ) { try { await this . redisClient . setExistence ( identifiers ) ; } catch ( error ) { debug ( error ) ; } } public async setRightNode ( rightNodes ) { try { await this . redisClient . setRightNode ( rightNodes ) ; } catch ( error ) { debug ( error ) ; } } public close ( ) { if ( this . tosv ) { clearTimeout ( this . tosv as NodeJS . Timer ) ; } } }