fix: 🐛 race condition between workers when creating note
Closes #10345 Discovered here: https://codeberg.org/calckey/calckey/issues/10345#issuecomment-950475
This commit is contained in:
parent
7640f4d3f8
commit
c0f6a53223
1 changed files with 34 additions and 20 deletions
|
@ -465,26 +465,40 @@ export default async (
|
||||||
if (!note.uri) {
|
if (!note.uri) {
|
||||||
// Publish if the post is local
|
// Publish if the post is local
|
||||||
publishNotesStream(note);
|
publishNotesStream(note);
|
||||||
} else if (
|
} else if (boostedByRelay && data.renote?.uri) {
|
||||||
boostedByRelay &&
|
// Use Redis transaction for atomicity
|
||||||
data.renote?.uri &&
|
await redisClient.watch(`publishedNote:${data.renote.uri}`);
|
||||||
(await redisClient.exists(`publishedNote:${data.renote.uri}`)) === 0
|
const exists = await redisClient.exists(
|
||||||
) {
|
`publishedNote:${data.renote.uri}`,
|
||||||
// Publish if the post was boosted by a relay and not yet published.
|
);
|
||||||
|
if (exists === 0) {
|
||||||
|
// Start the transaction
|
||||||
|
redisClient.multi();
|
||||||
publishNotesStream(data.renote);
|
publishNotesStream(data.renote);
|
||||||
const key = `publishedNote:${data.renote.uri}`;
|
const key = `publishedNote:${data.renote.uri}`;
|
||||||
await redisClient.set(key, 1, "EX", 30);
|
await redisClient.set(key, 1, "EX", 30);
|
||||||
} else if (
|
// Execute the transaction
|
||||||
!boostedByRelay &&
|
redisClient.exec();
|
||||||
note.uri &&
|
} else {
|
||||||
(await redisClient.exists(`publishedNote:${note.uri}`)) === 0
|
// Abort the transaction
|
||||||
) {
|
redisClient.unwatch();
|
||||||
// Publish if the post came directly from a remote server, or from a
|
}
|
||||||
// relay that doesn't boost the post (e.g, YUKIMOCHI Activity-Relay),
|
} else if (!boostedByRelay && note.uri) {
|
||||||
// and not yet published.
|
// Use Redis transaction for atomicity
|
||||||
const key = `publishedNote:${note.uri}`;
|
await redisClient.watch(`publishedNote:${note.uri}`);
|
||||||
|
const exists = await redisClient.exists(`publishedNote:${note.uri}`);
|
||||||
|
if (exists === 0) {
|
||||||
|
// Start the transaction
|
||||||
|
redisClient.multi();
|
||||||
publishNotesStream(note);
|
publishNotesStream(note);
|
||||||
|
const key = `publishedNote:${note.uri}`;
|
||||||
await redisClient.set(key, 1, "EX", 30);
|
await redisClient.set(key, 1, "EX", 30);
|
||||||
|
// Execute the transaction
|
||||||
|
redisClient.exec();
|
||||||
|
} else {
|
||||||
|
// Abort the transaction
|
||||||
|
redisClient.unwatch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (note.replyId != null) {
|
if (note.replyId != null) {
|
||||||
|
|
Loading…
Reference in a new issue