0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-24 23:48:13 -05:00

🐛 Fixed not reactivating email analytics jobs

no issue

When a site doesn't have any emails on boot, it doesn't schedule the email analytics job. With this change, the new email flow will also restart that job after an email has been created.
This commit is contained in:
Simon Backx 2023-01-26 17:32:34 +01:00
parent 6631071dd3
commit c798f383f9
4 changed files with 41 additions and 6 deletions

View file

@ -7,7 +7,7 @@ const jobsService = require('../../jobs');
let hasScheduled = false;
module.exports = {
async scheduleRecurringJobs() {
async scheduleRecurringJobs(skipEmailCheck = false) {
if (
!hasScheduled &&
config.get('emailAnalytics') &&
@ -17,10 +17,10 @@ module.exports = {
// Don't register email analytics job if we have no emails,
// processor usage from many sites spinning up threads can be high.
// Mega service will re-run this scheduling task when an email is sent
const emailCount = await models.Email
const emailCount = skipEmailCheck ? 1 : (await models.Email
.where('created_at', '>', moment.utc().subtract(30, 'days').toDate())
.where('status', '<>', 'failed')
.count();
.count());
if (emailCount > 0) {
// use a random seconds value to avoid spikes to external APIs on the minute

View file

@ -35,6 +35,7 @@ class EmailServiceWrapper {
const linkTracking = require('../link-tracking');
const audienceFeedback = require('../audience-feedback');
const storageUtils = require('../../adapters/storage/utils');
const emailAnalyticsJobs = require('../email-analytics/jobs');
// capture errors from mailgun client and log them in sentry
const errorHandler = (error) => {
@ -103,7 +104,8 @@ class EmailServiceWrapper {
emailSegmenter,
limitService,
membersRepository,
verificationTrigger: membersService.verificationTrigger
verificationTrigger: membersService.verificationTrigger,
emailAnalyticsJobs
});
this.controller = new EmailController(this.service, {

View file

@ -13,6 +13,7 @@ const tpl = require('@tryghost/tpl');
const EmailRenderer = require('./email-renderer');
const EmailSegmenter = require('./email-segmenter');
const SendingService = require('./sending-service');
const logging = require('@tryghost/logging');
const messages = {
archivedNewsletterError: 'Cannot send email to archived newsletters',
@ -30,6 +31,7 @@ class EmailService {
#limitService;
#membersRepository;
#verificationTrigger;
#emailAnalyticsJobs;
/**
*
@ -44,6 +46,7 @@ class EmailService {
* @param {LimitService} dependencies.limitService
* @param {object} dependencies.membersRepository
* @param {VerificationTrigger} dependencies.verificationTrigger
* @param {object} dependencies.emailAnalyticsJobs
*/
constructor({
batchSendingService,
@ -54,7 +57,8 @@ class EmailService {
emailSegmenter,
limitService,
membersRepository,
verificationTrigger
verificationTrigger,
emailAnalyticsJobs
}) {
this.#batchSendingService = batchSendingService;
this.#models = models;
@ -65,6 +69,7 @@ class EmailService {
this.#membersRepository = membersRepository;
this.#sendingService = sendingService;
this.#verificationTrigger = verificationTrigger;
this.#emailAnalyticsJobs = emailAnalyticsJobs;
}
/**
@ -141,6 +146,13 @@ class EmailService {
}, {patch: true});
}
// make sure recurring background analytics jobs are running once we have emails
try {
await this.#emailAnalyticsJobs.scheduleRecurringJobs(true);
} catch (e) {
logging.error(e);
}
return email;
}
async retryEmail(email) {

View file

@ -10,6 +10,7 @@ describe('Email Service', function () {
let membersRepository;
let emailRenderer;
let sendingService;
let scheduleRecurringJobs;
beforeEach(function () {
memberCount = 123;
@ -19,6 +20,7 @@ describe('Email Service', function () {
};
verificicationRequired = false;
scheduleEmail = sinon.stub().returns();
scheduleRecurringJobs = sinon.stub().resolves();
settings = {};
settingsCache = {
get(key) {
@ -85,7 +87,10 @@ describe('Email Service', function () {
settingsCache,
emailRenderer,
membersRepository,
sendingService
sendingService,
emailAnalyticsJobs: {
scheduleRecurringJobs
}
});
});
@ -155,6 +160,22 @@ describe('Email Service', function () {
assert.strictEqual(email.get('status'), 'pending');
assert.strictEqual(email.get('source'), post.get('mobiledoc'));
assert.strictEqual(email.get('source_type'), 'mobiledoc');
sinon.assert.calledOnce(scheduleRecurringJobs);
});
it('Ignores analytics job scheduling errors', async function () {
const post = createModel({
id: '123',
newsletter: createModel({
status: 'active',
feedback_enabled: true
}),
mobiledoc: 'Mobiledoc'
});
scheduleRecurringJobs.rejects(new Error('Test error'));
await service.createEmail(post);
sinon.assert.calledOnce(scheduleRecurringJobs);
});
it('Creates and schedules an email with lexical', async function () {