From 574112ff370455e9277281d6b7a599190275d623 Mon Sep 17 00:00:00 2001 From: Rebegea Dragos-Alexandru Date: Fri, 15 Sep 2023 09:37:47 +0300 Subject: [PATCH] MEX-366: cronjob for updating proposals and their statuses --- src/modules/governance/governance.module.ts | 1 + .../services/governance.setter.service.ts | 20 ++++++++- src/services/cache.warmer.module.ts | 4 ++ .../crons/governance.cache.warmer.service.ts | 43 +++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/services/crons/governance.cache.warmer.service.ts diff --git a/src/modules/governance/governance.module.ts b/src/modules/governance/governance.module.ts index d631f6058..5abf49072 100644 --- a/src/modules/governance/governance.module.ts +++ b/src/modules/governance/governance.module.ts @@ -63,6 +63,7 @@ import { LockedAssetModule } from '../locked-asset-factory/locked-asset.module'; GovernanceComputeService, GovernanceTokenSnapshotService, GovernanceEnergyService, + GovernanceAbiFactory, ], }) export class GovernanceModule {} diff --git a/src/modules/governance/services/governance.setter.service.ts b/src/modules/governance/services/governance.setter.service.ts index d3c92a417..b83656e51 100644 --- a/src/modules/governance/services/governance.setter.service.ts +++ b/src/modules/governance/services/governance.setter.service.ts @@ -5,7 +5,7 @@ import { CacheTtlInfo } from 'src/services/caching/cache.ttl.info'; import { GenericSetterService } from 'src/services/generics/generic.setter.service'; import { Logger } from 'winston'; import { ProposalVotes } from '../models/governance.proposal.votes.model'; -import { VoteType } from '../models/governance.proposal.model'; +import { GovernanceProposalModel, GovernanceProposalStatus, VoteType } from '../models/governance.proposal.model'; export class GovernanceSetterService extends GenericSetterService { constructor( @@ -42,4 +42,22 @@ export class GovernanceSetterService extends GenericSetterService { CacheTtlInfo.ContractState.localTtl, ); } + + async proposals(scAddress: string, value: GovernanceProposalModel[]): Promise { + return await this.setData( + this.getCacheKey('proposals', scAddress), + value, + CacheTtlInfo.ContractState.remoteTtl, + CacheTtlInfo.ContractState.localTtl, + ); + } + + async proposalStatus(scAddress: string, proposalId: number, value: GovernanceProposalStatus): Promise { + return await this.setData( + this.getCacheKey('proposalStatus', scAddress, proposalId), + value, + CacheTtlInfo.ContractState.remoteTtl, + CacheTtlInfo.ContractState.localTtl, + ); + } } diff --git a/src/services/cache.warmer.module.ts b/src/services/cache.warmer.module.ts index 000f89b73..5f61795d7 100644 --- a/src/services/cache.warmer.module.ts +++ b/src/services/cache.warmer.module.ts @@ -34,6 +34,8 @@ import { FarmModuleV1_2 } from 'src/modules/farm/v1.2/farm.v1.2.module'; import { FarmModuleV1_3 } from 'src/modules/farm/v1.3/farm.v1.3.module'; import { FarmModule } from 'src/modules/farm/farm.module'; import { AnalyticsModule as AnalyticsServicesModule } from 'src/services/analytics/analytics.module'; +import { GovernanceCacheWarmerService } from './crons/governance.cache.warmer.service'; +import { GovernanceModule } from '../modules/governance/governance.module'; @Module({ imports: [ @@ -58,6 +60,7 @@ import { AnalyticsModule as AnalyticsServicesModule } from 'src/services/analyti TokenModule, AnalyticsServicesModule, RemoteConfigModule, + GovernanceModule, ], controllers: [], providers: [ @@ -72,6 +75,7 @@ import { AnalyticsModule as AnalyticsServicesModule } from 'src/services/analyti AWSQueryCacheWarmerService, PriceDiscoveryCacheWarmerService, CachingService, + GovernanceCacheWarmerService, TransactionProcessorService, LogsProcessorService, ElasticService, diff --git a/src/services/crons/governance.cache.warmer.service.ts b/src/services/crons/governance.cache.warmer.service.ts new file mode 100644 index 000000000..afdc9a975 --- /dev/null +++ b/src/services/crons/governance.cache.warmer.service.ts @@ -0,0 +1,43 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { Cron } from '@nestjs/schedule'; +import { RedisPubSub } from 'graphql-redis-subscriptions'; +import { PUB_SUB } from '../redis.pubSub.module'; +import { governanceContractsAddresses, GovernanceType } from '../../utils/governance'; +import { GovernanceAbiFactory } from '../../modules/governance/services/governance.abi.factory'; +import { GovernanceSetterService } from '../../modules/governance/services/governance.setter.service'; + +@Injectable() +export class GovernanceCacheWarmerService { + constructor( + private readonly governanceAbiFactory: GovernanceAbiFactory, + private readonly governanceSetter: GovernanceSetterService, + @Inject(PUB_SUB) private pubSub: RedisPubSub, + ) {} + + @Cron('*/12 * * * * *') + async cacheGovernanceStatuses(): Promise { + const addresses = governanceContractsAddresses([ + GovernanceType.ENERGY, + GovernanceType.TOKEN_SNAPSHOT, + ]); + for (const address of addresses) { + const proposals = await this.governanceAbiFactory.useAbi(address).proposalsRaw(address); + const promises = []; + for (const proposal of proposals) { + const status = await this.governanceAbiFactory.useAbi(address).proposalStatusRaw(address, proposal.proposalId); + promises.push(this.governanceSetter.proposalStatus(address, proposal.proposalId, status)); + } + + const cachedKeys = await Promise.all([ + ...promises, + this.governanceSetter.proposals(address, proposals), + ]); + + await this.deleteCacheKeys(cachedKeys); + } + } + + private async deleteCacheKeys(invalidatedKeys: string[]) { + await this.pubSub.publish('deleteCacheKeys', invalidatedKeys); + } +}