Better logging for expiration timer updates

This commit is contained in:
Fedor Indutny 2022-06-20 15:43:16 -07:00 committed by GitHub
parent f9163f410e
commit 35e5eb847a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 84 additions and 54 deletions

View file

@ -2729,15 +2729,13 @@ export async function startApp(): Promise<void> {
const { expireTimer } = details; const { expireTimer } = details;
const isValidExpireTimer = typeof expireTimer === 'number'; const isValidExpireTimer = typeof expireTimer === 'number';
if (isValidExpireTimer) { if (isValidExpireTimer) {
await conversation.updateExpirationTimer( await conversation.updateExpirationTimer(expireTimer, {
expireTimer, source: window.ConversationController.getOurConversationId(),
window.ConversationController.getOurConversationId(), receivedAt: ev.receivedAtCounter,
undefined, fromSync: true,
{ isInitialSync,
fromSync: true, reason: 'contact sync',
isInitialSync, });
}
);
} }
} catch (error) { } catch (error) {
log.error('onContactReceived error:', Errors.toLogFormat(error)); log.error('onContactReceived error:', Errors.toLogFormat(error));
@ -2813,14 +2811,12 @@ export async function startApp(): Promise<void> {
return; return;
} }
await conversation.updateExpirationTimer( await conversation.updateExpirationTimer(expireTimer, {
expireTimer, fromSync: true,
window.ConversationController.getOurConversationId(), receivedAt: ev.receivedAtCounter,
undefined, source: window.ConversationController.getOurConversationId(),
{ reason: 'group sync',
fromSync: true, });
}
);
} }
// Received: // Received:

View file

@ -1870,7 +1870,9 @@ export async function createGroupV2({
conversation.trigger('newmessage', model); conversation.trigger('newmessage', model);
if (expireTimer) { if (expireTimer) {
await conversation.updateExpirationTimer(expireTimer); await conversation.updateExpirationTimer(expireTimer, {
reason: 'createGroupV2',
});
} }
return conversation; return conversation;

View file

@ -3288,7 +3288,9 @@ export class ConversationModel extends window.Backbone
`maybeApplyUniversalTimer(${this.idForLogging()}): applying timer` `maybeApplyUniversalTimer(${this.idForLogging()}): applying timer`
); );
await this.updateExpirationTimer(expireTimer); await this.updateExpirationTimer(expireTimer, {
reason: 'maybeApplyUniversalTimer',
});
} }
} }
@ -4446,19 +4448,27 @@ export class ConversationModel extends window.Backbone
async updateExpirationTimer( async updateExpirationTimer(
providedExpireTimer: number | undefined, providedExpireTimer: number | undefined,
providedSource?: unknown,
initiatingMessage?: MessageModel,
{ {
reason,
receivedAt,
receivedAtMS = Date.now(),
sentAt: providedSentAt,
source: providedSource,
fromSync = false, fromSync = false,
isInitialSync = false, isInitialSync = false,
fromGroupUpdate = false, fromGroupUpdate = false,
}: { }: {
reason: string;
receivedAt?: number;
receivedAtMS?: number;
sentAt?: number;
source?: string;
fromSync?: boolean; fromSync?: boolean;
isInitialSync?: boolean; isInitialSync?: boolean;
fromGroupUpdate?: boolean; fromGroupUpdate?: boolean;
} = {} }
): Promise<boolean | null | MessageModel | void> { ): Promise<boolean | null | MessageModel | void> {
const isSetByOther = providedSource || initiatingMessage; const isSetByOther = providedSource || providedSentAt !== undefined;
if (isGroupV2(this.attributes)) { if (isGroupV2(this.attributes)) {
if (isSetByOther) { if (isSetByOther) {
@ -4496,11 +4506,12 @@ export class ConversationModel extends window.Backbone
return null; return null;
} }
log.info("Update conversation 'expireTimer'", { const logId =
id: this.idForLogging(), `updateExpirationTimer(${this.idForLogging()}, ` +
expireTimer, `${expireTimer || 'disabled'}) ` +
source, `source=${source ?? '?'} reason=${reason}`;
});
log.info(`${logId}: updating`);
// if change wasn't made remotely, send it to the number/group // if change wasn't made remotely, send it to the number/group
if (!isSetByOther) { if (!isSetByOther) {
@ -4512,7 +4523,7 @@ export class ConversationModel extends window.Backbone
}); });
} catch (error) { } catch (error) {
log.error( log.error(
'updateExpirationTimer: Failed to queue expiration timer update', `${logId}: Failed to queue expiration timer update`,
Errors.toLogFormat(error) Errors.toLogFormat(error)
); );
throw error; throw error;
@ -4521,14 +4532,6 @@ export class ConversationModel extends window.Backbone
source = source || window.ConversationController.getOurConversationId(); source = source || window.ConversationController.getOurConversationId();
// When we add a disappearing messages notification to the conversation, we want it
// to be above the message that initiated that change, hence the subtraction.
const receivedAt =
initiatingMessage?.get('received_at') ||
window.Signal.Util.incrementMessageCounter();
const receivedAtMS = initiatingMessage?.get('received_at_ms') || Date.now();
const sentAt = (initiatingMessage?.get('sent_at') || receivedAtMS) - 1;
this.set({ expireTimer }); this.set({ expireTimer });
// This call actually removes universal timer notification and clears // This call actually removes universal timer notification and clears
@ -4537,6 +4540,10 @@ export class ConversationModel extends window.Backbone
window.Signal.Data.updateConversation(this.attributes); window.Signal.Data.updateConversation(this.attributes);
// When we add a disappearing messages notification to the conversation, we want it
// to be above the message that initiated that change, hence the subtraction.
const sentAt = (providedSentAt || receivedAtMS) - 1;
const model = new window.Whisper.Message({ const model = new window.Whisper.Message({
conversationId: this.id, conversationId: this.id,
expirationTimerUpdate: { expirationTimerUpdate: {
@ -4548,7 +4555,7 @@ export class ConversationModel extends window.Backbone
flags: Proto.DataMessage.Flags.EXPIRATION_TIMER_UPDATE, flags: Proto.DataMessage.Flags.EXPIRATION_TIMER_UPDATE,
readStatus: isInitialSync ? ReadStatus.Read : ReadStatus.Unread, readStatus: isInitialSync ? ReadStatus.Read : ReadStatus.Unread,
received_at_ms: receivedAtMS, received_at_ms: receivedAtMS,
received_at: receivedAt, received_at: receivedAt ?? window.Signal.Util.incrementMessageCounter(),
seenStatus: isInitialSync ? SeenStatus.Seen : SeenStatus.Unseen, seenStatus: isInitialSync ? SeenStatus.Seen : SeenStatus.Unseen,
sent_at: sentAt, sent_at: sentAt,
type: 'timer-notification', type: 'timer-notification',
@ -4566,6 +4573,10 @@ export class ConversationModel extends window.Backbone
this.addSingleMessage(message); this.addSingleMessage(message);
this.updateUnread(); this.updateUnread();
log.info(
`${logId}: added a notification received_at=${model.get('received_at')}`
);
return message; return message;
} }

View file

@ -2611,21 +2611,27 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if ( if (
dataMessage.expireTimer !== conversation.get('expireTimer') dataMessage.expireTimer !== conversation.get('expireTimer')
) { ) {
conversation.updateExpirationTimer( conversation.updateExpirationTimer(dataMessage.expireTimer, {
dataMessage.expireTimer,
source, source,
message, receivedAt: message.get('received_at'),
{ receivedAtMS: message.get('received_at_ms'),
fromGroupUpdate: isGroupUpdate(message.attributes), sentAt: message.get('sent_at'),
} fromGroupUpdate: isGroupUpdate(message.attributes),
); reason: `handleDataMessage(${this.idForLogging()})`,
});
} }
} else if ( } else if (
conversation.get('expireTimer') && conversation.get('expireTimer') &&
// We only turn off timers if it's not a group update // We only turn off timers if it's not a group update
!isGroupUpdate(message.attributes) !isGroupUpdate(message.attributes)
) { ) {
conversation.updateExpirationTimer(undefined, source, message); conversation.updateExpirationTimer(undefined, {
source,
receivedAt: message.get('received_at'),
receivedAtMS: message.get('received_at_ms'),
sentAt: message.get('sent_at'),
reason: `handleDataMessage(${this.idForLogging()})`,
});
} }
} }
} }

View file

@ -2723,7 +2723,10 @@ export default class MessageReceiver
const contactBuffer = new ContactBuffer(attachmentPointer.data); const contactBuffer = new ContactBuffer(attachmentPointer.data);
let contactDetails = contactBuffer.next(); let contactDetails = contactBuffer.next();
while (contactDetails !== undefined) { while (contactDetails !== undefined) {
const contactEvent = new ContactEvent(contactDetails); const contactEvent = new ContactEvent(
contactDetails,
envelope.receivedAtCounter
);
results.push(this.dispatchAndWait(contactEvent)); results.push(this.dispatchAndWait(contactEvent));
contactDetails = contactBuffer.next(); contactDetails = contactBuffer.next();
@ -2767,10 +2770,13 @@ export default class MessageReceiver
continue; continue;
} }
const ev = new GroupEvent({ const ev = new GroupEvent(
...groupDetails, {
id: Bytes.toBinary(id), ...groupDetails,
}); id: Bytes.toBinary(id),
},
envelope.receivedAtCounter
);
const promise = this.dispatchAndWait(ev).catch(e => { const promise = this.dispatchAndWait(ev).catch(e => {
log.error('error processing group', e); log.error('error processing group', e);
}); });

View file

@ -73,7 +73,10 @@ export class ErrorEvent extends Event {
} }
export class ContactEvent extends Event { export class ContactEvent extends Event {
constructor(public readonly contactDetails: ModifiedContactDetails) { constructor(
public readonly contactDetails: ModifiedContactDetails,
public readonly receivedAtCounter: number
) {
super('contact'); super('contact');
} }
} }
@ -90,7 +93,10 @@ export type GroupEventData = Omit<ModifiedGroupDetails, 'id'> &
}>; }>;
export class GroupEvent extends Event { export class GroupEvent extends Event {
constructor(public readonly groupDetails: GroupEventData) { constructor(
public readonly groupDetails: GroupEventData,
public readonly receivedAtCounter: number
) {
super('group'); super('group');
} }
} }

View file

@ -2552,7 +2552,10 @@ export class ConversationView extends window.Backbone.View<ConversationModel> {
await this.longRunningTaskWrapper({ await this.longRunningTaskWrapper({
name: 'updateExpirationTimer', name: 'updateExpirationTimer',
task: async () => model.updateExpirationTimer(valueToSet), task: async () =>
model.updateExpirationTimer(valueToSet, {
reason: 'setDisappearingMessages',
}),
}); });
} }