Refine UISI autorageshake conditions to cut down on false alarms (#7650)
The AutoRageshakeStore now only starts submitting rageshakes after the initial sync has completed, and provides a short grace period for decryption failures to resolve.pull/21833/head
parent
f99ae6d46a
commit
7e5de9294c
|
@ -15,6 +15,8 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src";
|
import { MatrixEvent } from "matrix-js-sdk/src";
|
||||||
|
import { sleep } from "matrix-js-sdk/src/utils";
|
||||||
|
import { ISyncStateData, SyncState } from "matrix-js-sdk/src/sync";
|
||||||
|
|
||||||
import SdkConfig from '../SdkConfig';
|
import SdkConfig from '../SdkConfig';
|
||||||
import sendBugReport from '../rageshake/submit-rageshake';
|
import sendBugReport from '../rageshake/submit-rageshake';
|
||||||
|
@ -23,14 +25,17 @@ import { AsyncStoreWithClient } from './AsyncStoreWithClient';
|
||||||
import { ActionPayload } from '../dispatcher/payloads';
|
import { ActionPayload } from '../dispatcher/payloads';
|
||||||
import SettingsStore from "../settings/SettingsStore";
|
import SettingsStore from "../settings/SettingsStore";
|
||||||
|
|
||||||
// Minimum interval of 5 minutes between reports, especially important when we're doing an initial sync with a lot of decryption errors
|
// Minimum interval of 1 minute between reports
|
||||||
const RAGESHAKE_INTERVAL = 5*60*1000;
|
const RAGESHAKE_INTERVAL = 60000;
|
||||||
|
// Before rageshaking, wait 5 seconds and see if the message has successfully decrypted
|
||||||
|
const GRACE_PERIOD = 5000;
|
||||||
// Event type for to-device messages requesting sender auto-rageshakes
|
// Event type for to-device messages requesting sender auto-rageshakes
|
||||||
const AUTO_RS_REQUEST = "im.vector.auto_rs_request";
|
const AUTO_RS_REQUEST = "im.vector.auto_rs_request";
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
reportedSessionIds: Set<string>;
|
reportedSessionIds: Set<string>;
|
||||||
lastRageshakeTime: number;
|
lastRageshakeTime: number;
|
||||||
|
initialSyncCompleted: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,9 +50,11 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient<IState> {
|
||||||
super(defaultDispatcher, {
|
super(defaultDispatcher, {
|
||||||
reportedSessionIds: new Set<string>(),
|
reportedSessionIds: new Set<string>(),
|
||||||
lastRageshakeTime: 0,
|
lastRageshakeTime: 0,
|
||||||
|
initialSyncCompleted: false,
|
||||||
});
|
});
|
||||||
this.onDecryptionAttempt = this.onDecryptionAttempt.bind(this);
|
this.onDecryptionAttempt = this.onDecryptionAttempt.bind(this);
|
||||||
this.onDeviceMessage = this.onDeviceMessage.bind(this);
|
this.onDeviceMessage = this.onDeviceMessage.bind(this);
|
||||||
|
this.onSyncStateChange = this.onSyncStateChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static get instance(): AutoRageshakeStore {
|
public static get instance(): AutoRageshakeStore {
|
||||||
|
@ -64,6 +71,7 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient<IState> {
|
||||||
if (this.matrixClient) {
|
if (this.matrixClient) {
|
||||||
this.matrixClient.on('Event.decrypted', this.onDecryptionAttempt);
|
this.matrixClient.on('Event.decrypted', this.onDecryptionAttempt);
|
||||||
this.matrixClient.on('toDeviceEvent', this.onDeviceMessage);
|
this.matrixClient.on('toDeviceEvent', this.onDeviceMessage);
|
||||||
|
this.matrixClient.on('sync', this.onSyncStateChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,9 +83,14 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient<IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async onDecryptionAttempt(ev: MatrixEvent): Promise<void> {
|
private async onDecryptionAttempt(ev: MatrixEvent): Promise<void> {
|
||||||
|
if (!this.state.initialSyncCompleted) { return; }
|
||||||
|
|
||||||
const wireContent = ev.getWireContent();
|
const wireContent = ev.getWireContent();
|
||||||
const sessionId = wireContent.session_id;
|
const sessionId = wireContent.session_id;
|
||||||
if (ev.isDecryptionFailure() && !this.state.reportedSessionIds.has(sessionId)) {
|
if (ev.isDecryptionFailure() && !this.state.reportedSessionIds.has(sessionId)) {
|
||||||
|
await sleep(GRACE_PERIOD);
|
||||||
|
if (!ev.isDecryptionFailure()) { return; }
|
||||||
|
|
||||||
const newReportedSessionIds = new Set(this.state.reportedSessionIds);
|
const newReportedSessionIds = new Set(this.state.reportedSessionIds);
|
||||||
await this.updateState({ reportedSessionIds: newReportedSessionIds.add(sessionId) });
|
await this.updateState({ reportedSessionIds: newReportedSessionIds.add(sessionId) });
|
||||||
|
|
||||||
|
@ -114,6 +127,12 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient<IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async onSyncStateChange(_state: SyncState, _prevState: SyncState, data: ISyncStateData) {
|
||||||
|
if (!this.state.initialSyncCompleted) {
|
||||||
|
await this.updateState({ initialSyncCompleted: !!data.nextSyncToken });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async onDeviceMessage(ev: MatrixEvent): Promise<void> {
|
private async onDeviceMessage(ev: MatrixEvent): Promise<void> {
|
||||||
if (ev.getType() !== AUTO_RS_REQUEST) return;
|
if (ev.getType() !== AUTO_RS_REQUEST) return;
|
||||||
const messageContent = ev.getContent();
|
const messageContent = ev.getContent();
|
||||||
|
|
Loading…
Reference in New Issue