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 { sleep } from "matrix-js-sdk/src/utils";
|
||||
import { ISyncStateData, SyncState } from "matrix-js-sdk/src/sync";
|
||||
|
||||
import SdkConfig from '../SdkConfig';
|
||||
import sendBugReport from '../rageshake/submit-rageshake';
|
||||
|
@ -23,14 +25,17 @@ import { AsyncStoreWithClient } from './AsyncStoreWithClient';
|
|||
import { ActionPayload } from '../dispatcher/payloads';
|
||||
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
|
||||
const RAGESHAKE_INTERVAL = 5*60*1000;
|
||||
// Minimum interval of 1 minute between reports
|
||||
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
|
||||
const AUTO_RS_REQUEST = "im.vector.auto_rs_request";
|
||||
|
||||
interface IState {
|
||||
reportedSessionIds: Set<string>;
|
||||
lastRageshakeTime: number;
|
||||
initialSyncCompleted: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,9 +50,11 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient<IState> {
|
|||
super(defaultDispatcher, {
|
||||
reportedSessionIds: new Set<string>(),
|
||||
lastRageshakeTime: 0,
|
||||
initialSyncCompleted: false,
|
||||
});
|
||||
this.onDecryptionAttempt = this.onDecryptionAttempt.bind(this);
|
||||
this.onDeviceMessage = this.onDeviceMessage.bind(this);
|
||||
this.onSyncStateChange = this.onSyncStateChange.bind(this);
|
||||
}
|
||||
|
||||
public static get instance(): AutoRageshakeStore {
|
||||
|
@ -64,6 +71,7 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient<IState> {
|
|||
if (this.matrixClient) {
|
||||
this.matrixClient.on('Event.decrypted', this.onDecryptionAttempt);
|
||||
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> {
|
||||
if (!this.state.initialSyncCompleted) { return; }
|
||||
|
||||
const wireContent = ev.getWireContent();
|
||||
const sessionId = wireContent.session_id;
|
||||
if (ev.isDecryptionFailure() && !this.state.reportedSessionIds.has(sessionId)) {
|
||||
await sleep(GRACE_PERIOD);
|
||||
if (!ev.isDecryptionFailure()) { return; }
|
||||
|
||||
const newReportedSessionIds = new Set(this.state.reportedSessionIds);
|
||||
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> {
|
||||
if (ev.getType() !== AUTO_RS_REQUEST) return;
|
||||
const messageContent = ev.getContent();
|
||||
|
|
Loading…
Reference in New Issue