Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/guides/running-in-web-server/running-in-web-server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,9 @@ Now we need to glue the server and the crawler together using the mapping of Cra

<CodeBlock language="js" title="src/web-server.mjs">{WebServerSource}</CodeBlock>

## The request queue keeps growing

Nothing empties a request queue on its own. Every incoming HTTP request gets its own `uniqueKey`, so none of them deduplicate either. The queue therefore holds one handled request for every request the server has served. The records are small, and on the Apify platform they live server-side. It only matters for a server staying up a very long time, where the answer is to recycle the process.

Do not reach for `purge()` while the crawler is running. It empties the whole queue, including requests added but not yet picked up. Every HTTP request still waiting is dropped and never answered, and its entry in `requestsToResponses` leaks. The more `maxConcurrency` throttles the crawler, the more requests are sitting there to lose.

22 changes: 19 additions & 3 deletions docs/upgrading/upgrading_v4.md
Original file line number Diff line number Diff line change
Expand Up @@ -615,17 +615,33 @@ The `purgeRequestQueue` option of `crawler.run()` went away with the automatic p
const crawler = new BasicCrawler({ requestHandler: async ({ request }) => { /* ... */ } });
await crawler.run(['https://example.com/a', 'https://example.com/b']);

const queue = await crawler.getRequestQueue();
await queue.purge?.();
const requestManager = await crawler.getRequestManager();
await requestManager.purge?.();

// The same URLs are crawled again:
await crawler.run(['https://example.com/a', 'https://example.com/c']);
```

`purge()` — empty the storage, keep its id and name — is new in v4 and available on `Dataset`, `KeyValueStore` and `RequestQueue`, as well as being an optional method on the `IRequestManager` interface.
`purge()` — empty the storage, keep its id and name — is new in v4 and available on `Dataset`, `KeyValueStore` and `RequestQueue`, as well as being an optional method on the `IRequestManager` interface. The Apify platform is the exception. Its API has no in-place empty, so all three throw there. The error points you at `drop()` or a fresh storage.

This has nothing to do with `purgeOnStart` / `CRAWLEE_PURGE_ON_START`, which still wipes the default storages once per process before the first run.

Most of the time you can avoid the purge entirely. Every crawler instance opens a request queue of its own (see the section above). A crawler per crawl therefore needs neither a purge nor any queue wiring. Pass `RequestQueue.open({ alias })` when you do want to hold on to that queue:

```typescript
for (const [index, urls] of batches.entries()) {
const crawler = new BasicCrawler({
// Optional — a fresh crawler gets its own queue anyway. Pass one to decide which.
requestManager: await RequestQueue.open({ alias: `batch-${index}` }),
requestHandler: async ({ request }) => { /* ... */ },
});

await crawler.run(urls);
}
```

An alias identifies a run-scoped queue. It has no persistent name, and is emptied on start along with the default storages. Reuse an alias and you get that same queue back, handled requests included. The next crawl then finds nothing to do. Give each crawl its own alias. `purge()` is for when one crawler and one queue must be reused.

### Storage `.open()` now also accepts `{ id?, name? }`

`Dataset.open()`, `KeyValueStore.open()`, and `RequestQueue.open()` previously accepted a single `idOrName?: string` parameter. This was ambiguous — callers couldn't express whether they were opening a storage by its ID or by name.
Expand Down
7 changes: 0 additions & 7 deletions test/e2e/playwright-multi-run/actor/.actor/actor.json

This file was deleted.

7 changes: 0 additions & 7 deletions test/e2e/playwright-multi-run/actor/.gitignore

This file was deleted.

26 changes: 0 additions & 26 deletions test/e2e/playwright-multi-run/actor/Dockerfile

This file was deleted.

30 changes: 0 additions & 30 deletions test/e2e/playwright-multi-run/actor/main.js

This file was deleted.

27 changes: 0 additions & 27 deletions test/e2e/playwright-multi-run/actor/package.json

This file was deleted.

14 changes: 0 additions & 14 deletions test/e2e/playwright-multi-run/test.mjs

This file was deleted.

Loading