0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-08 02:52:39 -05:00

Added cache config to stats endpoints (#19481)

no issue

Allows to enable cache via hostSettings.statsCache.enabled. This will
need proper cache timeouts in order to function correctly.

Usage in config:
```
"hostSettings": {
        "statsCache": {
            "enabled": true
        }
    },
    "adapters": {
        "cache": {
            "Redis": {
                "host": "127.0.0.1",
                "port": 6379,
                "username": "",
                "password": "",
                "ttl": 60,
                "storeConfig": {
                    "maxRetriesPerRequest": 1,
                    "enableOfflineQueue": false,
                    "retryConnectSeconds": 60
                }
            },
            "stats": {
                "adapter": "Redis",
                "ttl": 3600,
                "refreshAheadFactor": 1,
                "keyPrefix": "site:123456:stats"
            }
        }
    },
    ```
This commit is contained in:
Simon Backx 2024-01-18 15:26:49 +01:00 committed by GitHub
parent 57c5f92770
commit b30558c77c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 79 additions and 19 deletions

View file

@ -331,6 +331,7 @@ async function initServices({config}) {
const donationService = require('./server/services/donations');
const recommendationsService = require('./server/services/recommendations');
const emailAddressService = require('./server/services/email-address');
const statsService = require('./server/services/stats');
const urlUtils = require('./shared/url-utils');
@ -375,7 +376,8 @@ async function initServices({config}) {
mediaInliner.init(),
mailEvents.init(),
donationService.init(),
recommendationsService.init()
recommendationsService.init(),
statsService.init()
]);
debug('End: Services');

View file

@ -10,8 +10,14 @@ module.exports = {
docName: 'members',
method: 'browse'
},
cache: statsService.cache,
generateCacheKeyData() {
return {
method: 'memberCountHistory'
};
},
async query() {
return await statsService.getMemberCountHistory();
return await statsService.api.getMemberCountHistory();
}
},
mrr: {
@ -22,8 +28,14 @@ module.exports = {
docName: 'members',
method: 'browse'
},
cache: statsService.cache,
generateCacheKeyData() {
return {
method: 'mrr'
};
},
async query() {
return await statsService.getMRRHistory();
return await statsService.api.getMRRHistory();
}
},
subscriptions: {
@ -34,8 +46,15 @@ module.exports = {
docName: 'members',
method: 'browse'
},
cache: statsService.cache,
generateCacheKeyData() {
return {
method: 'subscriptions'
};
},
async query() {
return await statsService.getSubscriptionCountHistory();
return await statsService.api.getSubscriptionCountHistory();
}
},
postReferrers: {
@ -49,8 +68,18 @@ module.exports = {
docName: 'posts',
method: 'browse'
},
cache: statsService.cache,
generateCacheKeyData(frame) {
return {
method: 'postReferrers',
data: {
id: frame.data.id
}
};
},
async query(frame) {
return await statsService.getPostReferrers(frame.data.id);
return await statsService.api.getPostReferrers(frame.data.id);
}
},
referrersHistory: {
@ -64,8 +93,14 @@ module.exports = {
docName: 'posts',
method: 'browse'
},
cache: statsService.cache,
generateCacheKeyData() {
return {
method: 'referrersHistory'
};
},
async query() {
return await statsService.getReferrersHistory();
return await statsService.api.getReferrersHistory();
}
}
};

View file

@ -24,7 +24,7 @@ module.exports = class ExploreService {
*/
async fetchData() {
const totalMembers = await this.MembersService.stats.getTotalMembers();
const mrrStats = await this.StatsService.getMRRHistory();
const mrrStats = await this.StatsService.api.getMRRHistory();
const {description, icon, title, url, accent_color: accentColor, locale} = this.PublicConfigService.site;

View file

@ -1,4 +1,27 @@
const StatsService = require('@tryghost/stats-service');
const db = require('../../data/db');
class StatsServiceWrapper {
constructor() {
this.api = null;
this.cache = null;
}
module.exports = StatsService.create({knex: db.knex});
async init() {
if (this.api) {
// Already done
return;
}
const StatsService = require('@tryghost/stats-service');
const db = require('../../data/db');
this.api = StatsService.create({knex: db.knex});
const adapterManager = require('../adapter-manager');
const config = require('../../../shared/config');
if (config.get('hostSettings:statsCache:enabled')) {
this.cache = adapterManager.getAdapter('cache:stats');
}
}
}
module.exports = new StatsServiceWrapper();

View file

@ -53,7 +53,7 @@ describe('MRR Stats Service', function () {
describe('getCurrentMrr', function () {
it('Always returns at least one currency', async function () {
const result = await statsService.mrr.getCurrentMrr();
const result = await statsService.api.mrr.getCurrentMrr();
result.should.eql([
{
currency: 'usd', // need to check capital usage here!
@ -64,7 +64,7 @@ describe('MRR Stats Service', function () {
it('Can handle multiple currencies', async function () {
await createMemberWithSubscription('month', 500, 'eur', '2000-01-10');
const result = await statsService.mrr.getCurrentMrr();
const result = await statsService.api.mrr.getCurrentMrr();
result.should.eql([
{
currency: 'EUR',
@ -75,7 +75,7 @@ describe('MRR Stats Service', function () {
it('Increases MRR by 1 / 12 of yearly subscriptions', async function () {
await createMemberWithSubscription('year', 12, 'usd', '2000-01-10');
const result = await statsService.mrr.getCurrentMrr();
const result = await statsService.api.mrr.getCurrentMrr();
result.should.eql([
{
currency: 'EUR',
@ -90,7 +90,7 @@ describe('MRR Stats Service', function () {
it('Increases MRR with monthly subscriptions', async function () {
await createMemberWithSubscription('month', 1, 'usd', '2000-01-11');
const result = await statsService.mrr.getCurrentMrr();
const result = await statsService.api.mrr.getCurrentMrr();
result.should.eql([
{
currency: 'EUR',
@ -105,7 +105,7 @@ describe('MRR Stats Service', function () {
it('Floors results', async function () {
await createMemberWithSubscription('year', 17, 'usd', '2000-01-12');
let result = await statsService.mrr.getCurrentMrr();
let result = await statsService.api.mrr.getCurrentMrr();
result.should.eql([
{
currency: 'EUR',
@ -119,7 +119,7 @@ describe('MRR Stats Service', function () {
// Floor 11/12 to 0 (same as getMRRDelta method)
await createMemberWithSubscription('year', 11, 'usd', '2000-01-12');
result = await statsService.mrr.getCurrentMrr();
result = await statsService.api.mrr.getCurrentMrr();
result.should.eql([
{
currency: 'EUR',
@ -133,7 +133,7 @@ describe('MRR Stats Service', function () {
// Floor 11/12 to 0, don't combine with previous addition
await createMemberWithSubscription('year', 11, 'usd', '2000-01-12');
result = await statsService.mrr.getCurrentMrr();
result = await statsService.api.mrr.getCurrentMrr();
result.should.eql([
{
currency: 'EUR',
@ -147,7 +147,7 @@ describe('MRR Stats Service', function () {
// Floor 13/12 to 1
await createMemberWithSubscription('year', 13, 'usd', '2000-01-12');
result = await statsService.mrr.getCurrentMrr();
result = await statsService.api.mrr.getCurrentMrr();
result.should.eql([
{
currency: 'EUR',
@ -163,7 +163,7 @@ describe('MRR Stats Service', function () {
describe('fetchAllDeltas', function () {
it('Returns deltas in ascending order', async function () {
const results = await statsService.mrr.fetchAllDeltas();
const results = await statsService.api.mrr.fetchAllDeltas();
results.length.should.equal(4);
results.should.match([
{