fix: multiple boost publication by relay
This commit is contained in:
parent
ee5a08efdc
commit
44bf99e0c1
|
@ -461,31 +461,30 @@ export default async (
|
|||
}
|
||||
|
||||
if (!dontFederateInitially) {
|
||||
if (!note.userHost) {
|
||||
// Publish if the post is local
|
||||
publishNotesStream(note);
|
||||
} else {
|
||||
const relays = await getCachedRelays();
|
||||
// Some relays (e.g., aode-relay) deliver posts by boosting them as
|
||||
// Announce activities. In that case, user is the relay's actor.
|
||||
const boostedByRelay =
|
||||
!!user.inbox &&
|
||||
relays.map((relay) => relay.inbox).includes(user.inbox);
|
||||
const boostedByRelay = relays
|
||||
.map((relay) => new URL(relay.inbox).host)
|
||||
.includes(note.userHost);
|
||||
|
||||
if (!note.uri) {
|
||||
// Publish if the post is local
|
||||
publishNotesStream(note);
|
||||
} else if (boostedByRelay && data.renote?.uri) {
|
||||
if (boostedByRelay && data.renote) {
|
||||
// Use Redis transaction for atomicity
|
||||
await redisClient.watch(`publishedNote:${data.renote.uri}`);
|
||||
const exists = await redisClient.exists(
|
||||
`publishedNote:${data.renote.uri}`,
|
||||
);
|
||||
const key = `publishedNote:${data.renote.id}`;
|
||||
await redisClient.watch(key);
|
||||
const exists = await redisClient.exists(key);
|
||||
if (exists === 0) {
|
||||
// Start the transaction
|
||||
const transaction = redisClient.multi();
|
||||
const key = `publishedNote:${data.renote.uri}`;
|
||||
transaction.set(key, 1, "EX", 30);
|
||||
// Execute the transaction
|
||||
transaction.exec((err, replies) => {
|
||||
await transaction.exec((err, _replies) => {
|
||||
// Publish after setting the key in Redis
|
||||
if (!err && data.renote) {
|
||||
if (!err && boostedByRelay && data.renote) {
|
||||
publishNotesStream(data.renote);
|
||||
}
|
||||
});
|
||||
|
@ -493,17 +492,21 @@ export default async (
|
|||
// Abort the transaction
|
||||
redisClient.unwatch();
|
||||
}
|
||||
} else if (!boostedByRelay && note.uri) {
|
||||
} else {
|
||||
// Use Redis transaction for atomicity
|
||||
await redisClient.watch(`publishedNote:${note.uri}`);
|
||||
const exists = await redisClient.exists(`publishedNote:${note.uri}`);
|
||||
const key = `publishedNote:${note.id}`;
|
||||
await redisClient.watch(key);
|
||||
const exists = await redisClient.exists(key);
|
||||
if (exists === 0) {
|
||||
// Start the transaction
|
||||
const transaction = redisClient.multi();
|
||||
const key = `publishedNote:${note.uri}`;
|
||||
transaction.set(key, 1, "EX", 30);
|
||||
if (note.renoteId) {
|
||||
// Prevent other threads from publishing this boosting post
|
||||
transaction.set(`publishedNote:${note.renoteId}`, 1, "EX", 30);
|
||||
}
|
||||
// Execute the transaction
|
||||
transaction.exec((err, replies) => {
|
||||
await transaction.exec((err, _replies) => {
|
||||
// Publish after setting the key in Redis
|
||||
if (!err) {
|
||||
publishNotesStream(note);
|
||||
|
@ -515,6 +518,7 @@ export default async (
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (note.replyId != null) {
|
||||
// Only provide the reply note id here as the recipient may not be authorized to see the note.
|
||||
publishNoteStream(note.replyId, "replied", {
|
||||
|
|
Loading…
Reference in New Issue