diff --git a/src/modules/governance/governance.module.ts b/src/modules/governance/governance.module.ts index ed5dc02e9..25aa133fb 100644 --- a/src/modules/governance/governance.module.ts +++ b/src/modules/governance/governance.module.ts @@ -66,6 +66,7 @@ import { ElasticService } from 'src/helpers/elastic.service'; 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 f37000ec6..a905506bf 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 e89b2e11d..c64221484 100644 --- a/src/services/cache.warmer.module.ts +++ b/src/services/cache.warmer.module.ts @@ -33,6 +33,8 @@ import { FarmModule } from 'src/modules/farm/farm.module'; import { AnalyticsModule as AnalyticsServicesModule } from 'src/services/analytics/analytics.module'; import { ElasticService } from 'src/helpers/elastic.service'; import { DynamicModuleUtils } from 'src/utils/dynamic.module.utils'; +import { GovernanceCacheWarmerService } from './crons/governance.cache.warmer.service'; +import { GovernanceModule } from '../modules/governance/governance.module'; @Module({ imports: [ @@ -56,6 +58,7 @@ import { DynamicModuleUtils } from 'src/utils/dynamic.module.utils'; TokenModule, AnalyticsServicesModule, RemoteConfigModule, + GovernanceModule, DynamicModuleUtils.getCacheModule(), ], controllers: [], @@ -70,6 +73,7 @@ import { DynamicModuleUtils } from 'src/utils/dynamic.module.utils'; AnalyticsCacheWarmerService, AWSQueryCacheWarmerService, PriceDiscoveryCacheWarmerService, + 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); + } +}