perf: optimize RequestList memory footprint#2466
Conversation
|
Here is the run with 4 million items in RL with the patch: https://console.apify.com/actors/Tcx7qJL5NP2PvmZ5c/runs/tuKGnab8BqrKlILHC#log
And the time to process the first request since And here without the patch: https://console.apify.com/actors/Tcx7qJL5NP2PvmZ5c/runs/qSuwhtHPzcS1N0WpN#log
The time to process the first request since |
RequestList memory footprint
ce071e7 to
87c3e55
Compare
| private ensureRequest(requestLike: Request | RequestOptions, index: number): Request { | ||
| if (requestLike instanceof Request) { | ||
| return requestLike; | ||
| } | ||
|
|
||
| this.requests[index] = new Request(requestLike); | ||
| return this.requests[index] as Request; | ||
| } |
There was a problem hiding this comment.
This is a bit unclear to me, why do we want to store the Request object back in the array?
Wouldn't something like
makeRequest(r: RequestLike) : Request {
if(r instanceof Request) return r;
return new Request(r);
}work just fine? Or do the (possible) repeated request constructions pose a performance problem?
There was a problem hiding this comment.
because when we reclaim requests, we need to reclaim the same request object that was returned via fetchNextRequest (otherwise tests break, haven't been debugging why more in detail)
will add a comment for this
There was a problem hiding this comment.
fetchNextRequest would still return a Request instance... the same one we would pass to reclaim later even.
But whatever, let's treat this as a hotfix, I assume the Delivery team depends on this. We'll revisit this in v4 either way, judging by the comments in Request?
There was a problem hiding this comment.
the thing is, you need to persist the reclaimed requests, and that needs to happen with their metadata (e.g. userData), if we wouldn't do this, we would loose that completely on migration. at least i think so.
|
Last thing to deal with, migrations are broken: |
| } | ||
|
|
||
| protected _computeUniqueKey({ url, method, payload, keepUrlFragment, useExtendedUniqueKey }: ComputeUniqueKeyOptions) { | ||
| // TODO: only for better BC, remove in v4 |
There was a problem hiding this comment.
Please make an issue to track that 🙂
There was a problem hiding this comment.
we have other things in the code that are marked just with a TODO, since they are only about removing stuff (namely the old variants for crawler options like handlePageFunction). we can create one issue for all of such things later, for now i'd say a todo in the code is enough.
(but other than that I am on your side, i dislike TODOs in code very much, since they are always left forgotten, lol)
There was a problem hiding this comment.
Well, there is a rule in Ruff (Python linter) that forces you to add issue links to TODO comments, and while it's a pain in the backside, it prevents forgotten TODOs 🙂
Maybe we could do something similar - it would even make it possible to estimate the difficulty of a "Remove v4 TODOs" issue.
| const name: string = null; | ||
| const sources = [{ url: 'https://example.com' }]; | ||
| const requests = sources.map(({ url }) => new Request({ url })); | ||
| const requests = sources.map(({ url }) => ({ url, uniqueKey: url })); |
There was a problem hiding this comment.
Are you changing this so that it passes the equality check? Also, it'd be nice to call that variable expectedRequests or something.
There was a problem hiding this comment.
new Request creates the unique key in the constructor
|
Looks like this is actually expected behaviour, the RL needs to be named or you need to provide |


The request list now delays the conversion of the source items into the
Requestobjects, resulting in a significantly less memory footprint.Related: https://apify.slack.com/archives/C0L33UM7Z/p1715109984834079