-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
jump to end of reports on init, better handle missing next_token
#360
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,7 @@ export class ReportPoller { | |
* https://matrix-org.github.io/synapse/latest/admin_api/event_reports.html | ||
* "from" is an opaque token that is returned from the API to paginate reports | ||
*/ | ||
private from = 0; | ||
private from: number | null = null; | ||
/** | ||
* The currently-pending report poll | ||
*/ | ||
|
@@ -60,26 +60,32 @@ export class ReportPoller { | |
} | ||
|
||
private async getAbuseReports() { | ||
let params: { dir: string, from?: number} = { | ||
// short for direction: forward; i.e. show newest last | ||
dir: "f", | ||
} | ||
if (this.from !== null) { | ||
params["from"] = this.from; | ||
} | ||
|
||
let response_: { | ||
event_reports: { room_id: string, event_id: string, sender: string, reason: string }[], | ||
next_token: number | undefined | ||
next_token: number | undefined, | ||
total: number, | ||
} | undefined; | ||
try { | ||
response_ = await this.mjolnir.client.doRequest( | ||
"GET", | ||
"/_synapse/admin/v1/event_reports", | ||
{ | ||
// short for direction: forward; i.e. show newest last | ||
dir: "f", | ||
from: this.from.toString() | ||
} | ||
params, | ||
); | ||
} catch (ex) { | ||
await this.mjolnir.logMessage(LogLevel.ERROR, "getAbuseReports", `failed to poll events: ${ex}`); | ||
return; | ||
} | ||
|
||
const response = response_!; | ||
|
||
for (let report of response.event_reports) { | ||
if (!(report.room_id in this.mjolnir.protectedRooms)) { | ||
continue; | ||
|
@@ -104,18 +110,29 @@ export class ReportPoller { | |
}); | ||
} | ||
|
||
/* | ||
* This API endpoint returns an opaque `next_token` number that we | ||
* need to give back to subsequent requests for pagination, so here we | ||
* save it in account data | ||
*/ | ||
if (response.next_token !== undefined) { | ||
this.from = response.next_token; | ||
try { | ||
await this.mjolnir.client.setAccountData(REPORT_POLL_EVENT_TYPE, { from: response.next_token }); | ||
} catch (ex) { | ||
await this.mjolnir.logMessage(LogLevel.ERROR, "getAbuseReports", `failed to update progress: ${ex}`); | ||
} | ||
let from; | ||
if (this.from === null) { | ||
/* | ||
* If this is our first call to this endpoint, we want to skip to | ||
* the end of available reports, so we'll only consider reports | ||
* that happened after we supported report polling. | ||
*/ | ||
from = response.total; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That sounds fishy. Isn't |
||
} else { | ||
/* | ||
* If there are more pages for us to read, this endpoint will | ||
* return an opaque `next_token` number that we want to provide | ||
* on the next endpoint call. If not, we're on the last page, | ||
* which means we want to skip to the end of this page. | ||
*/ | ||
from = response.next_token ?? this.from + response.event_reports.length; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this.from + response.event_reports.length isn't ideal because the |
||
} | ||
|
||
this.from = from; | ||
try { | ||
await this.mjolnir.client.setAccountData(REPORT_POLL_EVENT_TYPE, { from: from }); | ||
} catch (ex) { | ||
await this.mjolnir.logMessage(LogLevel.ERROR, "getAbuseReports", `failed to update progress: ${ex}`); | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right that we want to do something to avoid displaying tens of thousands of old reports the first time we start the Report Poller on the server.
I believe that we should rather:
ReportPoller
.from
from Mjölnir's account data.from
a. Fetch a cutout date from the configuration, or some default date if not specified (say August 1st 2022).
b. Start background enumerating all reports until the cutout date, without displaying them.
c. Use this to initialize
from
. This may also give us a first few abuse reports that will need to be returned the first time we callgetAbuseReports
.d. Store this value of
from
in Mjölnir's account data.getAbuseReports
.from
(which may benull
if the server has never encountered any abuse report).from
, store it in Mjölnir's account data.What do you think?