fix: use expiry from swarm to update readAt & expiresAt for msg

pull/2940/head
Audric Ackermann 1 year ago
parent 82c6f0897b
commit 5cfbb8405c

@ -1157,26 +1157,18 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
} }
public isExpired() { public isExpired() {
return this.msTilExpire() <= 0;
}
public msTilExpire() {
if (!this.isExpiring()) { if (!this.isExpiring()) {
return Infinity; return false;
} }
const now = Date.now(); const now = Date.now();
const start = this.getExpirationStartTimestamp(); const start = this.getExpirationStartTimestamp();
if (!start) { if (!start) {
return Infinity; return false;
} }
const delta = this.getExpireTimer() * 1000; const delta = this.getExpireTimer() * 1000;
let msFromNow = start + delta - now; const msFromNow = start + delta - now;
if (msFromNow < 0) { return msFromNow < 0;
msFromNow = 0;
}
return msFromNow;
} }
public async setToExpire() { public async setToExpire() {
if (this.isExpiring() && !this.getExpiresAt()) { if (this.isExpiring() && !this.getExpiresAt()) {
const start = this.getExpirationStartTimestamp(); const start = this.getExpirationStartTimestamp();

@ -31,6 +31,7 @@ export interface MessageAttributes {
expirationType?: DisappearingMessageType; expirationType?: DisappearingMessageType;
/** in seconds, 0 means no expiration */ /** in seconds, 0 means no expiration */
expireTimer: number; expireTimer: number;
/** in milliseconds */
expirationStartTimestamp: number; expirationStartTimestamp: number;
expires_at?: number; expires_at?: number;
expirationTimerUpdate?: ExpirationTimerUpdate; expirationTimerUpdate?: ExpirationTimerUpdate;

@ -148,8 +148,8 @@ export async function processExpireRequestResponse(
return results; return results;
} }
type UpdatedExpiryWithHashes = { messageHashes: Array<string>; updatedExpiry: number }; type UpdatedExpiryWithHashes = { messageHashes: Array<string>; updatedExpiryMs: number };
type UpdatedExpiryWithHash = { messageHash: string; updatedExpiry: number }; type UpdatedExpiryWithHash = { messageHash: string; updatedExpiryMs: number };
async function updateExpiryOnNodes( async function updateExpiryOnNodes(
targetNode: Snode, targetNode: Snode,
@ -210,7 +210,7 @@ async function updateExpiryOnNodes(
} }
changesValid.push({ changesValid.push({
messageHashes: expirationResult.hashes, messageHashes: expirationResult.hashes,
updatedExpiry: expirationResult.expiry, updatedExpiryMs: expirationResult.expiry,
}); });
} }
@ -222,17 +222,16 @@ async function updateExpiryOnNodes(
// we requested hashes which are not part of the result. They most likely expired already so let's mark those messages as expiring now. // we requested hashes which are not part of the result. They most likely expired already so let's mark those messages as expiring now.
changesValid.push({ changesValid.push({
messageHashes: hashesRequestedButNotInResults, messageHashes: hashesRequestedButNotInResults,
updatedExpiry: Date.now(), updatedExpiryMs: Date.now(),
}); });
} }
const expiryWithIndividualHash: Array<UpdatedExpiryWithHash> = flatten( const expiryWithIndividualHash: Array<UpdatedExpiryWithHash> = flatten(
changesValid.map(change => changesValid.map(change =>
change.messageHashes.map(h => ({ messageHash: h, updatedExpiry: change.updatedExpiry })) change.messageHashes.map(h => ({ messageHash: h, updatedExpiryMs: change.updatedExpiryMs }))
) )
); );
debugger; window.log.debug('update expiry expiryWithIndividualHash: ', expiryWithIndividualHash);
console.warn('update expiry expiryWithIndividualHash: ', expiryWithIndividualHash);
return expiryWithIndividualHash; return expiryWithIndividualHash;
} catch (err) { } catch (err) {
// NOTE batch requests have their own retry logic which includes abort errors that will break our retry logic so we need to catch them and throw regular errors // NOTE batch requests have their own retry logic which includes abort errors that will break our retry logic so we need to catch them and throw regular errors
@ -373,7 +372,7 @@ export type ExpiringDetails = Array<
export async function expireMessagesOnSnode( export async function expireMessagesOnSnode(
expiringDetails: ExpiringDetails, expiringDetails: ExpiringDetails,
options: WithShortenOrExtend options: WithShortenOrExtend
): Promise<Array<{ messageHash: string; updatedExpiry: number }>> { ): Promise<Array<{ messageHash: string; updatedExpiryMs: number }>> {
const ourPubKey = UserUtils.getOurPubKeyStrFromCache(); const ourPubKey = UserUtils.getOurPubKeyStrFromCache();
if (!ourPubKey) { if (!ourPubKey) {
throw new Error('[expireMessageOnSnode] No pubkey found'); throw new Error('[expireMessageOnSnode] No pubkey found');

@ -79,10 +79,22 @@ async function destroyExpiredMessages() {
messages.forEach(expired => { messages.forEach(expired => {
window.log.info('Message expired', { window.log.info('Message expired', {
sentAt: expired.get('sent_at'), sentAt: expired.get('sent_at'),
hash: expired.getMessageHash(),
}); });
}); });
await destroyMessagesAndUpdateRedux(messagesExpiredDetails); await destroyMessagesAndUpdateRedux(messagesExpiredDetails);
const convosToRefresh = uniq(messagesExpiredDetails.map(m => m.conversationKey));
await Promise.all(
convosToRefresh.map(async c => {
getConversationController()
.get(c)
?.updateLastMessage();
return getConversationController()
.get(c)
?.refreshInMemoryDetails();
})
);
} catch (error) { } catch (error) {
window.log.error( window.log.error(
'destroyExpiredMessages: Error deleting expired messages', 'destroyExpiredMessages: Error deleting expired messages',
@ -552,7 +564,7 @@ async function updateMessageExpiriesOnSwarm(messages: Array<MessageModel>) {
window.log.debug(`[updateMessageExpiriesOnSwarm] no expiringDetails to update`); window.log.debug(`[updateMessageExpiriesOnSwarm] no expiringDetails to update`);
return; return;
} }
console.warn('expiringDetails', expiringDetails); window.log.debug('updateMessageExpiriesOnSwarm: expiringDetails', expiringDetails);
const newTTLs = await expireMessagesOnSnode(expiringDetails, { shortenOrExtend: 'shorten' }); const newTTLs = await expireMessagesOnSnode(expiringDetails, { shortenOrExtend: 'shorten' });
const updatedMsgModels: Array<MessageModel> = []; const updatedMsgModels: Array<MessageModel> = [];
@ -562,10 +574,23 @@ async function updateMessageExpiriesOnSwarm(messages: Array<MessageModel>) {
return; return;
} }
const newTTL = m.updatedExpiry; const newTTLms = m.updatedExpiryMs;
if (newTTL && newTTL !== message.getExpiresAt()) { const realReadAt = newTTLms - message.getExpireTimer() * 1000;
if (
newTTLms &&
(newTTLms !== message.getExpiresAt() ||
message.get('expirationStartTimestamp') !== realReadAt) &&
message.getExpireTimer()
) {
window.log.debug(`updateMessageExpiriesOnSwarm: setting for msg hash ${m.messageHash}:`, {
expires_at: newTTLms,
expirationStartTimestamp: realReadAt,
unread: READ_MESSAGE_STATE.read,
});
message.set({ message.set({
expires_at: newTTL, expires_at: newTTLms,
expirationStartTimestamp: realReadAt,
unread: READ_MESSAGE_STATE.read,
}); });
updatedMsgModels.push(message); updatedMsgModels.push(message);

@ -2,6 +2,7 @@
import { compact, isEmpty, isNumber, uniq } from 'lodash'; import { compact, isEmpty, isNumber, uniq } from 'lodash';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { Data } from '../../../../data/data'; import { Data } from '../../../../data/data';
import { READ_MESSAGE_STATE } from '../../../../models/conversationAttributes';
import { MessageModel } from '../../../../models/message'; import { MessageModel } from '../../../../models/message';
import { isSignInByLinking } from '../../../../util/storage'; import { isSignInByLinking } from '../../../../util/storage';
import { getExpiriesFromSnode } from '../../../apis/snode_api/getExpiriesRequest'; import { getExpiriesFromSnode } from '../../../apis/snode_api/getExpiriesRequest';
@ -66,13 +67,31 @@ class FetchMsgExpirySwarmJob extends PersistedJob<FetchMsgExpirySwarmPersistedDa
if (expiry.fetchedExpiry <= 0) { if (expiry.fetchedExpiry <= 0) {
continue; continue;
} }
const found = msgModels.find(m => m.getMessageHash() === expiry.messageHash); const message = msgModels.find(m => m.getMessageHash() === expiry.messageHash);
if (!found) { if (!message) {
continue; continue;
} }
if (found.get('expires_at') !== expiry.fetchedExpiry) { const realReadAt = expiry.fetchedExpiry - message.getExpireTimer() * 1000;
found.set('expires_at', expiry.fetchedExpiry);
updatedMsgModels.push(found); if (
(message.get('expirationStartTimestamp') !== realReadAt ||
message.get('expires_at') !== expiry.fetchedExpiry) &&
message.getExpireTimer()
) {
window.log.debug(
`FetchMsgExpirySwarmJob: setting for msg hash ${message.getMessageHash()}:`,
{
expires_at: expiry.fetchedExpiry,
unread: READ_MESSAGE_STATE.read,
expirationStartTimestamp: realReadAt,
}
);
message.set({
expires_at: expiry.fetchedExpiry,
unread: READ_MESSAGE_STATE.read,
expirationStartTimestamp: realReadAt,
});
updatedMsgModels.push(message);
} }
} }
} }

Loading…
Cancel
Save