Skip to content

Commit 7243cd3

Browse files
committed
Transaction Fix
1 parent dcba434 commit 7243cd3

3 files changed

Lines changed: 82 additions & 78 deletions

File tree

RELEASE_NOTES.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
### 🐛 Bug Fixes
66

7-
- TypeScript errors fixed.
87
- Various bug fixes and optimizations.
98

109
### 📚 Docs

apps/backend/src/cron/processQueuedCampaigns.ts

Lines changed: 81 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -159,41 +159,43 @@ export const processQueuedCampaigns = cronJob(
159159
continue
160160
}
161161

162-
await prisma.$transaction(async (tx) => {
163-
const linkTracker = new LinkTracker(tx)
164-
const messagesToCreate: Prisma.MessageCreateManyInput[] = []
165-
166-
for (const subscriber of subscribersToProcess) {
167-
const messageId = uuidV4()
168-
if (!campaign.content) {
169-
oneTimeLogger(
170-
"missingCampaignContent",
171-
`Cron job: Campaign ${campaign.id} has no content. Skipping.`
172-
)
173-
continue
174-
}
162+
await prisma.$transaction(
163+
async (tx) => {
164+
const linkTracker = new LinkTracker(tx)
165+
const messagesToCreate: Prisma.MessageCreateManyInput[] = []
166+
167+
for (const subscriber of subscribersToProcess) {
168+
const messageId = uuidV4()
169+
if (!campaign.content) {
170+
oneTimeLogger(
171+
"missingCampaignContent",
172+
`Cron job: Campaign ${campaign.id} has no content. Skipping.`
173+
)
174+
continue
175+
}
175176

176-
turnOnLogger("missingCampaignContent")
177+
turnOnLogger("missingCampaignContent")
177178

178-
let emailContent = campaign.Template
179-
? campaign.Template.content.replace(
180-
/{{content}}/g,
181-
campaign.content
182-
)
183-
: campaign.content
179+
let emailContent = campaign.Template
180+
? campaign.Template.content.replace(
181+
/{{content}}/g,
182+
campaign.content
183+
)
184+
: campaign.content
184185

185-
if (!campaign.subject) {
186-
oneTimeLogger(
187-
"missingCampaignSubject",
188-
`Cron job: Campaign ${campaign.id} has no subject. Skipping.`
189-
)
190-
continue
191-
}
186+
if (!campaign.subject) {
187+
oneTimeLogger(
188+
"missingCampaignSubject",
189+
`Cron job: Campaign ${campaign.id} has no subject. Skipping.`
190+
)
191+
continue
192+
}
192193

193-
turnOnLogger("missingCampaignSubject")
194+
turnOnLogger("missingCampaignSubject")
194195

195-
const placeholderData: Partial<Record<PlaceholderDataKey, string>> =
196-
{
196+
const placeholderData: Partial<
197+
Record<PlaceholderDataKey, string>
198+
> = {
197199
"subscriber.email": subscriber.email,
198200
"campaign.name": campaign.title,
199201
"campaign.subject": campaign.subject,
@@ -202,59 +204,62 @@ export const processQueuedCampaigns = cronJob(
202204
current_date: new Date().toLocaleDateString("en-CA"),
203205
}
204206

205-
if (campaign.openTracking) {
206-
emailContent += `<img src="${generalSettings.baseURL}/img/${messageId}/img.png" alt="" width="1" height="1" style="display:none" />`
207-
}
207+
if (campaign.openTracking) {
208+
emailContent += `<img src="${generalSettings.baseURL}/img/${messageId}/img.png" alt="" width="1" height="1" style="display:none" />`
209+
}
208210

209-
if (subscriber.name) {
210-
placeholderData["subscriber.name"] = subscriber.name
211-
}
212-
if (subscriber.Metadata) {
213-
for (const meta of subscriber.Metadata) {
214-
placeholderData[`subscriber.metadata.${meta.key}`] = meta.value
211+
if (subscriber.name) {
212+
placeholderData["subscriber.name"] = subscriber.name
213+
}
214+
if (subscriber.Metadata) {
215+
for (const meta of subscriber.Metadata) {
216+
placeholderData[`subscriber.metadata.${meta.key}`] =
217+
meta.value
218+
}
215219
}
216-
}
217220

218-
emailContent = replacePlaceholders(emailContent, placeholderData)
221+
emailContent = replacePlaceholders(emailContent, placeholderData)
219222

220-
if (!generalSettings.baseURL) {
221-
console.error(
222-
`Cron job: Campaign ${campaign.id} has no baseURL. Skipping.`
223-
)
224-
continue
223+
if (!generalSettings.baseURL) {
224+
console.error(
225+
`Cron job: Campaign ${campaign.id} has no baseURL. Skipping.`
226+
)
227+
continue
228+
}
229+
230+
const { content: finalContent } =
231+
await linkTracker.replaceMessageContentWithTrackedLinks(
232+
emailContent,
233+
campaign.id,
234+
generalSettings.baseURL
235+
)
236+
237+
messagesToCreate.push({
238+
id: messageId,
239+
campaignId: campaign.id,
240+
subscriberId: subscriber.id,
241+
content: finalContent,
242+
status: "QUEUED",
243+
})
225244
}
226245

227-
const { content: finalContent } =
228-
await linkTracker.replaceMessageContentWithTrackedLinks(
229-
emailContent,
230-
campaign.id,
231-
generalSettings.baseURL
232-
)
246+
if (messagesToCreate.length > 0) {
247+
await tx.message.createMany({
248+
data: messagesToCreate,
249+
})
250+
251+
await tx.campaign.update({
252+
where: { id: campaign.id },
253+
data: { status: "SENDING" },
254+
})
233255

234-
messagesToCreate.push({
235-
id: messageId,
236-
campaignId: campaign.id,
237-
subscriberId: subscriber.id,
238-
content: finalContent,
239-
status: "QUEUED",
240-
})
241-
}
242-
243-
if (messagesToCreate.length > 0) {
244-
await tx.message.createMany({
245-
data: messagesToCreate,
246-
})
247-
248-
await tx.campaign.update({
249-
where: { id: campaign.id },
250-
data: { status: "SENDING" },
251-
})
252-
253-
console.log(
254-
`Cron job: Created ${messagesToCreate.length} messages for campaign ${campaign.id}.`
255-
)
256-
}
257-
}) // End transaction
256+
console.log(
257+
`Cron job: Created ${messagesToCreate.length} messages for campaign ${campaign.id}.`
258+
)
259+
}
260+
},
261+
{ timeout: 60_000 }
262+
) // End transaction
258263

259264
turnOnLogger("errorProcessingCampaign")
260265
} catch (error) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "0.5.2",
2+
"version": "0.5.3",
33
"name": "letterspace",
44
"private": true,
55
"scripts": {

0 commit comments

Comments
 (0)