@crawlee/core 4.0.0-beta.98 → 4.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/autoscaling/autoscaled_pool.d.ts +3 -21
- package/autoscaling/autoscaled_pool.js +105 -97
- package/autoscaling/concurrency_system.d.ts +7 -22
- package/autoscaling/concurrency_system.js +112 -100
- package/autoscaling/cpu_load_signal.d.ts +1 -2
- package/autoscaling/cpu_load_signal.js +11 -10
- package/autoscaling/event_loop_load_signal.d.ts +1 -4
- package/autoscaling/event_loop_load_signal.js +18 -18
- package/autoscaling/index.d.ts +1 -1
- package/autoscaling/index.js +1 -1
- package/autoscaling/load_signal.d.ts +8 -7
- package/autoscaling/load_signal.js +14 -12
- package/autoscaling/memory_load_signal.d.ts +3 -12
- package/autoscaling/memory_load_signal.js +41 -41
- package/autoscaling/snapshotter.d.ts +7 -10
- package/autoscaling/snapshotter.js +18 -18
- package/autoscaling/{client_load_signal.d.ts → storage_backend_load_signal.d.ts} +14 -17
- package/autoscaling/{client_load_signal.js → storage_backend_load_signal.js} +27 -27
- package/autoscaling/system_status.d.ts +9 -11
- package/autoscaling/system_status.js +13 -13
- package/configuration.d.ts +16 -16
- package/configuration.js +6 -6
- package/crawlers/context_pipeline.js +6 -6
- package/crawlers/crawler_commons.d.ts +14 -116
- package/crawlers/crawler_commons.js +1 -107
- package/crawlers/error_snapshotter.d.ts +2 -4
- package/crawlers/error_snapshotter.js +5 -5
- package/crawlers/index.d.ts +1 -1
- package/crawlers/index.js +0 -1
- package/crawlers/statistics.d.ts +164 -45
- package/crawlers/statistics.js +339 -153
- package/debug.js +4 -4
- package/enqueue_links/enqueue_links.d.ts +51 -159
- package/enqueue_links/enqueue_links.js +38 -231
- package/enqueue_links/shared.d.ts +34 -24
- package/enqueue_links/shared.js +54 -36
- package/errors.d.ts +43 -12
- package/errors.js +48 -9
- package/events/event_manager.d.ts +2 -2
- package/events/event_manager.js +7 -6
- package/events/local_event_manager.d.ts +1 -1
- package/events/local_event_manager.js +5 -5
- package/http.d.ts +9 -0
- package/http.js +28 -0
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/log.js +5 -1
- package/memory-storage/memory-storage.d.ts +3 -11
- package/memory-storage/memory-storage.js +42 -48
- package/memory-storage/resource-clients/dataset.d.ts +1 -1
- package/memory-storage/resource-clients/dataset.js +8 -13
- package/memory-storage/resource-clients/key-value-store.d.ts +1 -1
- package/memory-storage/resource-clients/key-value-store.js +36 -38
- package/memory-storage/resource-clients/request-queue.d.ts +4 -23
- package/memory-storage/resource-clients/request-queue.js +68 -80
- package/owned_or_injected.d.ts +1 -3
- package/owned_or_injected.js +17 -17
- package/package.json +8 -9
- package/proxy_configuration.d.ts +1 -3
- package/proxy_configuration.js +18 -14
- package/recoverable_state.d.ts +80 -45
- package/recoverable_state.js +163 -75
- package/request.d.ts +3 -4
- package/request.js +57 -44
- package/router.d.ts +6 -10
- package/router.js +23 -23
- package/serialization.js +14 -13
- package/service_locator.d.ts +19 -10
- package/service_locator.js +57 -48
- package/session_pool/session.d.ts +3 -14
- package/session_pool/session.js +76 -74
- package/session_pool/session_pool.d.ts +6 -12
- package/session_pool/session_pool.js +85 -77
- package/storages/batched_adds.d.ts +37 -0
- package/storages/batched_adds.js +73 -0
- package/storages/dataset.d.ts +12 -1
- package/storages/dataset.js +133 -32
- package/storages/index.d.ts +2 -1
- package/storages/index.js +2 -1
- package/storages/key_value_store.d.ts +19 -4
- package/storages/key_value_store.js +204 -75
- package/storages/request_dedup_cache.d.ts +1 -2
- package/storages/request_dedup_cache.js +9 -9
- package/storages/request_list.d.ts +4 -23
- package/storages/request_list.js +103 -96
- package/storages/request_loader.d.ts +5 -0
- package/storages/request_manager_tandem.d.ts +1 -10
- package/storages/request_manager_tandem.js +27 -27
- package/storages/request_queue.d.ts +21 -21
- package/storages/request_queue.js +318 -177
- package/storages/sitemap_request_loader.d.ts +22 -70
- package/storages/sitemap_request_loader.js +122 -116
- package/storages/storage_instance_manager.d.ts +1 -4
- package/storages/storage_instance_manager.js +17 -19
- package/storages/storage_stats.d.ts +1 -1
- package/storages/storage_stats.js +4 -4
- package/storages/throttling_request_manager.d.ts +239 -0
- package/storages/throttling_request_manager.js +646 -0
- package/storages/transaction.d.ts +252 -0
- package/storages/transaction.js +251 -0
- package/storages/utils.d.ts +6 -3
- package/storages/utils.js +11 -2
- package/system-info/runtime.js +7 -7
- package/url.d.ts +9 -0
- package/url.js +11 -0
- package/validators.d.ts +22 -25
- package/validators.js +13 -25
- package/storages/access_checking.d.ts +0 -12
- package/storages/access_checking.js +0 -17
|
@@ -65,20 +65,9 @@ export interface SessionOptions {
|
|
|
65
65
|
* @category Scaling
|
|
66
66
|
*/
|
|
67
67
|
export declare class Session implements ISession {
|
|
68
|
+
#private;
|
|
68
69
|
readonly id: string;
|
|
69
70
|
readonly userData: Dictionary;
|
|
70
|
-
private _maxErrorScore;
|
|
71
|
-
private _errorScoreDecrement;
|
|
72
|
-
private _createdAt;
|
|
73
|
-
private _expiresAt;
|
|
74
|
-
private _usageCount;
|
|
75
|
-
private _maxUsageCount;
|
|
76
|
-
private _errorScore;
|
|
77
|
-
private _retired;
|
|
78
|
-
private _proxyInfo?;
|
|
79
|
-
private _cookieJar;
|
|
80
|
-
private _fingerprint?;
|
|
81
|
-
private log;
|
|
82
71
|
get errorScore(): number;
|
|
83
72
|
get usageCount(): number;
|
|
84
73
|
get maxErrorScore(): number;
|
|
@@ -149,11 +138,11 @@ export declare class Session implements ISession {
|
|
|
149
138
|
* a cookie header or elsewhere.
|
|
150
139
|
* @returns Represents `Cookie` header.
|
|
151
140
|
*/
|
|
152
|
-
getCookieString(url: string): string
|
|
141
|
+
getCookieString(url: string): Promise<string>;
|
|
153
142
|
/**
|
|
154
143
|
* Sets a cookie within this session for the specific URL.
|
|
155
144
|
*/
|
|
156
|
-
setCookie(rawCookie: string, url: string): void
|
|
145
|
+
setCookie(rawCookie: string, url: string): Promise<void>;
|
|
157
146
|
/**
|
|
158
147
|
* Checks if session is not usable. if it is not retires the session.
|
|
159
148
|
*/
|
package/session_pool/session.js
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
|
-
import ow from 'ow';
|
|
2
1
|
import { CookieJar } from 'tough-cookie';
|
|
2
|
+
import { z } from 'zod';
|
|
3
3
|
import { cryptoRandomObjectId } from '@apify/utilities';
|
|
4
4
|
import { getDefaultCookieExpirationDate } from '../cookie_utils.js';
|
|
5
5
|
import { serviceLocator } from '../service_locator.js';
|
|
6
|
+
import { parseArgument, schemas, validators } from '../validators.js';
|
|
7
|
+
// `schemas.anyObject` passes values through by reference (object schemas return a pruned plain
|
|
8
|
+
// copy), so class instances like cookie jars and loggers keep their prototype.
|
|
9
|
+
const sessionOptionsSchema = z.strictObject({
|
|
10
|
+
id: z.string().default(() => `session_${cryptoRandomObjectId(10)}`),
|
|
11
|
+
cookieJar: schemas.anyObject.default(() => new CookieJar()),
|
|
12
|
+
proxyInfo: schemas.anyObject.optional(),
|
|
13
|
+
maxAgeSecs: schemas.anyNumber.default(3000),
|
|
14
|
+
userData: schemas.anyObject.default(() => ({})),
|
|
15
|
+
maxErrorScore: schemas.anyNumber.default(3),
|
|
16
|
+
errorScoreDecrement: schemas.anyNumber.default(0.5),
|
|
17
|
+
createdAt: z.date().default(() => new Date()),
|
|
18
|
+
expiresAt: z.date().optional(),
|
|
19
|
+
usageCount: schemas.anyNumber.default(0),
|
|
20
|
+
errorScore: schemas.anyNumber.default(0),
|
|
21
|
+
maxUsageCount: schemas.anyNumber.default(50),
|
|
22
|
+
retired: z.boolean().default(false),
|
|
23
|
+
log: validators.logger.default(() => serviceLocator.getLogger()),
|
|
24
|
+
fingerprint: schemas.anyObject.optional(),
|
|
25
|
+
});
|
|
6
26
|
/**
|
|
7
27
|
* Sessions are used to store information such as cookies and can be used for generating fingerprints and proxy sessions.
|
|
8
28
|
* You can imagine each session as a specific user, with its own cookies, IP (via proxy) and potentially a unique browser fingerprint.
|
|
@@ -12,96 +32,78 @@ import { serviceLocator } from '../service_locator.js';
|
|
|
12
32
|
export class Session {
|
|
13
33
|
id;
|
|
14
34
|
userData;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
log;
|
|
35
|
+
#maxErrorScore;
|
|
36
|
+
#errorScoreDecrement;
|
|
37
|
+
#createdAt;
|
|
38
|
+
#expiresAt;
|
|
39
|
+
#usageCount;
|
|
40
|
+
#maxUsageCount;
|
|
41
|
+
#errorScore;
|
|
42
|
+
#retired = false;
|
|
43
|
+
#proxyInfo;
|
|
44
|
+
#cookieJar;
|
|
45
|
+
#fingerprint;
|
|
46
|
+
#log;
|
|
27
47
|
get errorScore() {
|
|
28
|
-
return this
|
|
48
|
+
return this.#errorScore;
|
|
29
49
|
}
|
|
30
50
|
get usageCount() {
|
|
31
|
-
return this
|
|
51
|
+
return this.#usageCount;
|
|
32
52
|
}
|
|
33
53
|
get maxErrorScore() {
|
|
34
|
-
return this
|
|
54
|
+
return this.#maxErrorScore;
|
|
35
55
|
}
|
|
36
56
|
get errorScoreDecrement() {
|
|
37
|
-
return this
|
|
57
|
+
return this.#errorScoreDecrement;
|
|
38
58
|
}
|
|
39
59
|
get expiresAt() {
|
|
40
|
-
return this
|
|
60
|
+
return this.#expiresAt;
|
|
41
61
|
}
|
|
42
62
|
get createdAt() {
|
|
43
|
-
return this
|
|
63
|
+
return this.#createdAt;
|
|
44
64
|
}
|
|
45
65
|
get maxUsageCount() {
|
|
46
|
-
return this
|
|
66
|
+
return this.#maxUsageCount;
|
|
47
67
|
}
|
|
48
68
|
get cookieJar() {
|
|
49
|
-
return this
|
|
69
|
+
return this.#cookieJar;
|
|
50
70
|
}
|
|
51
71
|
get proxyInfo() {
|
|
52
|
-
return this
|
|
72
|
+
return this.#proxyInfo;
|
|
53
73
|
}
|
|
54
74
|
get fingerprint() {
|
|
55
|
-
return this
|
|
75
|
+
return this.#fingerprint;
|
|
56
76
|
}
|
|
57
77
|
set fingerprint(fingerprint) {
|
|
58
|
-
this
|
|
78
|
+
this.#fingerprint = fingerprint;
|
|
59
79
|
}
|
|
60
80
|
/**
|
|
61
81
|
* `true` once {@link Session.retire|`retire()`} has been called. Retirement is terminal:
|
|
62
82
|
* a retired session is never picked by the pool and cannot be revived via `markGood()`.
|
|
63
83
|
*/
|
|
64
84
|
get retired() {
|
|
65
|
-
return this
|
|
85
|
+
return this.#retired;
|
|
66
86
|
}
|
|
67
87
|
/**
|
|
68
88
|
* Session configuration.
|
|
69
89
|
*/
|
|
70
90
|
constructor(options = {}) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
userData: ow.optional.object,
|
|
77
|
-
maxErrorScore: ow.optional.number,
|
|
78
|
-
errorScoreDecrement: ow.optional.number,
|
|
79
|
-
createdAt: ow.optional.date,
|
|
80
|
-
expiresAt: ow.optional.date,
|
|
81
|
-
usageCount: ow.optional.number,
|
|
82
|
-
errorScore: ow.optional.number,
|
|
83
|
-
maxUsageCount: ow.optional.number,
|
|
84
|
-
retired: ow.optional.boolean,
|
|
85
|
-
log: ow.optional.object,
|
|
86
|
-
fingerprint: ow.optional.object,
|
|
87
|
-
}));
|
|
88
|
-
const { id = `session_${cryptoRandomObjectId(10)}`, cookieJar = new CookieJar(), proxyInfo = undefined, maxAgeSecs = 3000, userData = {}, maxErrorScore = 3, errorScoreDecrement = 0.5, createdAt = new Date(), usageCount = 0, errorScore = 0, maxUsageCount = 50, retired = false, log = serviceLocator.getLogger(), fingerprint, } = options;
|
|
89
|
-
const { expiresAt = getDefaultCookieExpirationDate(maxAgeSecs) } = options;
|
|
90
|
-
this.log = log.child({ prefix: 'Session' });
|
|
91
|
-
this._cookieJar = cookieJar.setCookie ? cookieJar : CookieJar.fromJSON(JSON.stringify(cookieJar));
|
|
92
|
-
this._proxyInfo = proxyInfo;
|
|
93
|
-
this._fingerprint = fingerprint;
|
|
91
|
+
const { id, cookieJar, proxyInfo, maxAgeSecs, userData, maxErrorScore, errorScoreDecrement, createdAt, usageCount, errorScore, maxUsageCount, retired, log, fingerprint, expiresAt = getDefaultCookieExpirationDate(maxAgeSecs), } = parseArgument(options, sessionOptionsSchema);
|
|
92
|
+
this.#log = log.child({ prefix: 'Session' });
|
|
93
|
+
this.#cookieJar = cookieJar.setCookie ? cookieJar : CookieJar.fromJSON(JSON.stringify(cookieJar));
|
|
94
|
+
this.#proxyInfo = proxyInfo;
|
|
95
|
+
this.#fingerprint = fingerprint;
|
|
94
96
|
this.id = id;
|
|
95
97
|
this.userData = userData;
|
|
96
|
-
this
|
|
97
|
-
this
|
|
98
|
+
this.#maxErrorScore = maxErrorScore;
|
|
99
|
+
this.#errorScoreDecrement = errorScoreDecrement;
|
|
98
100
|
// Internal
|
|
99
|
-
this
|
|
100
|
-
this
|
|
101
|
-
this
|
|
102
|
-
this
|
|
103
|
-
this
|
|
104
|
-
this
|
|
101
|
+
this.#expiresAt = expiresAt;
|
|
102
|
+
this.#createdAt = createdAt;
|
|
103
|
+
this.#usageCount = usageCount; // indicates how many times the session has been used
|
|
104
|
+
this.#errorScore = errorScore; // indicates number of markBaded request with the session
|
|
105
|
+
this.#maxUsageCount = maxUsageCount;
|
|
106
|
+
this.#retired = retired;
|
|
105
107
|
}
|
|
106
108
|
/**
|
|
107
109
|
* Indicates whether the session is blocked.
|
|
@@ -130,16 +132,16 @@ export class Session {
|
|
|
130
132
|
* Session is usable when it is not retired, not expired, not blocked and the maximum usage count has not be reached.
|
|
131
133
|
*/
|
|
132
134
|
isUsable() {
|
|
133
|
-
return !this
|
|
135
|
+
return !this.#retired && !this.isBlocked() && !this.isExpired() && !this.isMaxUsageCountReached();
|
|
134
136
|
}
|
|
135
137
|
/**
|
|
136
138
|
* This method should be called after a successful session usage.
|
|
137
139
|
* It increases `usageCount` and potentially lowers the `errorScore` by the `errorScoreDecrement`.
|
|
138
140
|
*/
|
|
139
141
|
markGood() {
|
|
140
|
-
this
|
|
141
|
-
if (this
|
|
142
|
-
this
|
|
142
|
+
this.#usageCount += 1;
|
|
143
|
+
if (this.#errorScore > 0) {
|
|
144
|
+
this.#errorScore -= this.#errorScoreDecrement;
|
|
143
145
|
}
|
|
144
146
|
this.maybeSelfRetire();
|
|
145
147
|
}
|
|
@@ -151,9 +153,9 @@ export class Session {
|
|
|
151
153
|
return {
|
|
152
154
|
id: this.id,
|
|
153
155
|
cookieJar: this.cookieJar.toJSON(),
|
|
154
|
-
proxyInfo: this
|
|
156
|
+
proxyInfo: this.#proxyInfo,
|
|
155
157
|
userData: this.userData,
|
|
156
|
-
fingerprint: this
|
|
158
|
+
fingerprint: this.#fingerprint,
|
|
157
159
|
maxErrorScore: this.maxErrorScore,
|
|
158
160
|
errorScoreDecrement: this.errorScoreDecrement,
|
|
159
161
|
expiresAt: this.expiresAt.toISOString(),
|
|
@@ -161,7 +163,7 @@ export class Session {
|
|
|
161
163
|
usageCount: this.usageCount,
|
|
162
164
|
maxUsageCount: this.maxUsageCount,
|
|
163
165
|
errorScore: this.errorScore,
|
|
164
|
-
retired: this
|
|
166
|
+
retired: this.#retired,
|
|
165
167
|
};
|
|
166
168
|
}
|
|
167
169
|
/**
|
|
@@ -172,19 +174,19 @@ export class Session {
|
|
|
172
174
|
* For transient external failures (such as `5XX` responses), use `markBad()` instead.
|
|
173
175
|
*/
|
|
174
176
|
retire() {
|
|
175
|
-
if (this
|
|
177
|
+
if (this.#retired)
|
|
176
178
|
return;
|
|
177
|
-
this
|
|
178
|
-
this
|
|
179
|
-
this
|
|
179
|
+
this.#errorScore += this.#maxErrorScore;
|
|
180
|
+
this.#usageCount += 1;
|
|
181
|
+
this.#retired = true;
|
|
180
182
|
}
|
|
181
183
|
/**
|
|
182
184
|
* Increases usage and error count.
|
|
183
185
|
* Should be used when the session has been used unsuccessfully. For example because of timeouts.
|
|
184
186
|
*/
|
|
185
187
|
markBad() {
|
|
186
|
-
this
|
|
187
|
-
this
|
|
188
|
+
this.#errorScore += 1;
|
|
189
|
+
this.#usageCount += 1;
|
|
188
190
|
this.maybeSelfRetire();
|
|
189
191
|
}
|
|
190
192
|
/**
|
|
@@ -193,18 +195,18 @@ export class Session {
|
|
|
193
195
|
* a cookie header or elsewhere.
|
|
194
196
|
* @returns Represents `Cookie` header.
|
|
195
197
|
*/
|
|
196
|
-
getCookieString(url) {
|
|
197
|
-
return this.cookieJar.
|
|
198
|
+
async getCookieString(url) {
|
|
199
|
+
return this.cookieJar.getCookieString(url, {});
|
|
198
200
|
}
|
|
199
201
|
/**
|
|
200
202
|
* Sets a cookie within this session for the specific URL.
|
|
201
203
|
*/
|
|
202
|
-
setCookie(rawCookie, url) {
|
|
204
|
+
async setCookie(rawCookie, url) {
|
|
203
205
|
try {
|
|
204
|
-
this.cookieJar.
|
|
206
|
+
await this.cookieJar.setCookie(rawCookie, url);
|
|
205
207
|
}
|
|
206
208
|
catch (e) {
|
|
207
|
-
this
|
|
209
|
+
this.#log.warning('Could not set cookie.', { url, error: e.message });
|
|
208
210
|
}
|
|
209
211
|
}
|
|
210
212
|
/**
|
|
@@ -112,24 +112,15 @@ export interface SessionPoolOptions {
|
|
|
112
112
|
* @category Scaling
|
|
113
113
|
*/
|
|
114
114
|
export declare class SessionPool implements ISessionPool {
|
|
115
|
-
private
|
|
115
|
+
#private;
|
|
116
116
|
readonly id: string;
|
|
117
|
-
private log;
|
|
118
117
|
private maxPoolSize;
|
|
119
118
|
private createSessionFunction;
|
|
120
119
|
private keyValueStore?;
|
|
121
|
-
private sessions;
|
|
122
120
|
private sessionMap;
|
|
123
121
|
private sessionOptions;
|
|
124
122
|
private persistStateKeyValueStoreId?;
|
|
125
123
|
private persistStateKey;
|
|
126
|
-
private listener?;
|
|
127
|
-
private events;
|
|
128
|
-
private persistenceOptions;
|
|
129
|
-
private sessionReuseStrategy;
|
|
130
|
-
private initPromise?;
|
|
131
|
-
private queue;
|
|
132
|
-
private roundRobinIndex;
|
|
133
124
|
constructor(options?: SessionPoolOptions);
|
|
134
125
|
/**
|
|
135
126
|
* Gets count of usable sessions in the pool.
|
|
@@ -190,8 +181,11 @@ export declare class SessionPool implements ISessionPool {
|
|
|
190
181
|
/**
|
|
191
182
|
* Removes listener from `persistState` event.
|
|
192
183
|
* This function should be called after you are done with using the `SessionPool` instance.
|
|
184
|
+
* @param options - Set `persistState` to false when the final state was already persisted by the event manager.
|
|
193
185
|
*/
|
|
194
|
-
teardown(
|
|
186
|
+
teardown({ persistState }?: {
|
|
187
|
+
persistState?: boolean;
|
|
188
|
+
}): Promise<void>;
|
|
195
189
|
/**
|
|
196
190
|
* Removes retired `Session` instances from `SessionPool`.
|
|
197
191
|
*/
|
|
@@ -222,7 +216,7 @@ export declare class SessionPool implements ISessionPool {
|
|
|
222
216
|
* through `maybeLoadSessionPool` naturally wins because it arrives in
|
|
223
217
|
* `perCallOptions`.
|
|
224
218
|
*/
|
|
225
|
-
private
|
|
219
|
+
private invokeCreateSessionFunction;
|
|
226
220
|
/**
|
|
227
221
|
* Creates new session and adds it to the pool.
|
|
228
222
|
* @returns Newly created `Session` instance.
|