@crawlee/core 4.0.0-beta.105 → 4.0.0-beta.106
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 +85 -85
- package/autoscaling/client_load_signal.d.ts +1 -5
- package/autoscaling/client_load_signal.js +20 -20
- package/autoscaling/concurrency_system.d.ts +5 -20
- package/autoscaling/concurrency_system.js +81 -80
- package/autoscaling/cpu_load_signal.d.ts +1 -2
- package/autoscaling/cpu_load_signal.js +10 -10
- package/autoscaling/event_loop_load_signal.d.ts +1 -4
- package/autoscaling/event_loop_load_signal.js +18 -18
- package/autoscaling/load_signal.d.ts +1 -1
- package/autoscaling/load_signal.js +12 -11
- package/autoscaling/memory_load_signal.d.ts +3 -12
- package/autoscaling/memory_load_signal.js +40 -41
- package/autoscaling/snapshotter.d.ts +1 -4
- package/autoscaling/snapshotter.js +12 -12
- package/autoscaling/system_status.d.ts +1 -3
- package/autoscaling/system_status.js +11 -11
- package/configuration.d.ts +1 -1
- package/configuration.js +3 -3
- package/crawlers/context_pipeline.js +6 -6
- package/crawlers/statistics.d.ts +1 -8
- package/crawlers/statistics.js +45 -44
- package/events/event_manager.d.ts +1 -1
- package/events/event_manager.js +3 -3
- package/events/local_event_manager.d.ts +1 -1
- package/events/local_event_manager.js +3 -3
- package/log.js +5 -1
- package/memory-storage/memory-storage.d.ts +1 -5
- package/memory-storage/memory-storage.js +2 -2
- package/memory-storage/resource-clients/dataset.d.ts +1 -1
- package/memory-storage/resource-clients/dataset.js +6 -5
- package/memory-storage/resource-clients/key-value-store.d.ts +1 -1
- package/memory-storage/resource-clients/key-value-store.js +13 -12
- package/memory-storage/resource-clients/request-queue.d.ts +4 -23
- package/memory-storage/resource-clients/request-queue.js +59 -58
- package/owned_or_injected.d.ts +1 -3
- package/owned_or_injected.js +17 -17
- package/package.json +5 -5
- package/proxy_configuration.d.ts +1 -3
- package/proxy_configuration.js +8 -8
- package/recoverable_state.d.ts +1 -10
- package/recoverable_state.js +41 -41
- package/request.d.ts +1 -2
- package/request.js +10 -13
- package/router.d.ts +1 -4
- package/router.js +23 -23
- package/serialization.js +8 -9
- package/service_locator.d.ts +1 -10
- package/service_locator.js +48 -48
- package/session_pool/session.d.ts +1 -12
- package/session_pool/session.js +50 -50
- package/session_pool/session_pool.d.ts +2 -11
- package/session_pool/session_pool.js +59 -58
- package/storages/dataset.d.ts +1 -1
- package/storages/dataset.js +5 -5
- package/storages/key_value_store.d.ts +1 -4
- package/storages/key_value_store.js +21 -20
- package/storages/request_dedup_cache.d.ts +1 -2
- package/storages/request_dedup_cache.js +9 -9
- package/storages/request_list.d.ts +2 -22
- package/storages/request_list.js +74 -73
- package/storages/request_manager_tandem.d.ts +1 -10
- package/storages/request_manager_tandem.js +27 -27
- package/storages/request_queue.d.ts +2 -18
- package/storages/request_queue.js +37 -35
- package/storages/sitemap_request_loader.d.ts +1 -44
- package/storages/sitemap_request_loader.js +87 -87
- package/storages/storage_instance_manager.d.ts +1 -2
- package/storages/storage_instance_manager.js +17 -17
- package/storages/storage_stats.d.ts +1 -1
- package/storages/storage_stats.js +4 -4
- package/storages/transaction.d.ts +1 -3
- package/storages/transaction.js +17 -17
- package/system-info/runtime.js +7 -7
|
@@ -120,8 +120,8 @@ class StorageCache {
|
|
|
120
120
|
* assigns a reserved default alias.
|
|
121
121
|
*/
|
|
122
122
|
export class StorageInstanceManager {
|
|
123
|
-
cache = new StorageCache();
|
|
124
|
-
openerLocks = new Map();
|
|
123
|
+
#cache = new StorageCache();
|
|
124
|
+
#openerLocks = new Map();
|
|
125
125
|
/**
|
|
126
126
|
* Open (or retrieve from cache) a storage instance.
|
|
127
127
|
*
|
|
@@ -142,46 +142,46 @@ export class StorageInstanceManager {
|
|
|
142
142
|
}
|
|
143
143
|
// Fast-path cache check (no lock).
|
|
144
144
|
if (alias !== undefined) {
|
|
145
|
-
const cached = this
|
|
145
|
+
const cached = this.#cache.get(cls, { alias, backendCacheKey });
|
|
146
146
|
if (cached)
|
|
147
147
|
return cached;
|
|
148
148
|
}
|
|
149
149
|
else if (id) {
|
|
150
|
-
const cached = this
|
|
150
|
+
const cached = this.#cache.get(cls, { id, backendCacheKey });
|
|
151
151
|
if (cached)
|
|
152
152
|
return cached;
|
|
153
153
|
}
|
|
154
154
|
else if (name) {
|
|
155
|
-
const cached = this
|
|
155
|
+
const cached = this.#cache.get(cls, { name, backendCacheKey });
|
|
156
156
|
if (cached)
|
|
157
157
|
return cached;
|
|
158
158
|
}
|
|
159
159
|
const identifierKey = id ?? name ?? alias ?? DEFAULT_STORAGE_ALIAS;
|
|
160
160
|
const lockKey = `${cls.name}:${identifierKey}:${backendCacheKey}`;
|
|
161
|
-
if (!this
|
|
162
|
-
this
|
|
161
|
+
if (!this.#openerLocks.has(lockKey)) {
|
|
162
|
+
this.#openerLocks.set(lockKey, new AsyncQueue());
|
|
163
163
|
}
|
|
164
|
-
const queue = this
|
|
164
|
+
const queue = this.#openerLocks.get(lockKey);
|
|
165
165
|
await queue.wait();
|
|
166
166
|
try {
|
|
167
167
|
// Double-check cache under lock (another caller may have filled it while we waited).
|
|
168
168
|
if (alias !== undefined) {
|
|
169
|
-
const cached = this
|
|
169
|
+
const cached = this.#cache.get(cls, { alias, backendCacheKey });
|
|
170
170
|
if (cached)
|
|
171
171
|
return cached;
|
|
172
172
|
}
|
|
173
173
|
else if (id) {
|
|
174
|
-
const cached = this
|
|
174
|
+
const cached = this.#cache.get(cls, { id, backendCacheKey });
|
|
175
175
|
if (cached)
|
|
176
176
|
return cached;
|
|
177
177
|
}
|
|
178
178
|
else if (name) {
|
|
179
|
-
const cached = this
|
|
179
|
+
const cached = this.#cache.get(cls, { name, backendCacheKey });
|
|
180
180
|
if (cached)
|
|
181
181
|
return cached;
|
|
182
182
|
}
|
|
183
183
|
// Prevent the same string from being used as both a name and an alias.
|
|
184
|
-
this
|
|
184
|
+
this.#cache.checkNameAliasConflict(cls, { name, alias, backendCacheKey });
|
|
185
185
|
// Cache miss — create the sub-backend and storage instance.
|
|
186
186
|
const subBackend = await backendOpener();
|
|
187
187
|
const storageInfo = await subBackend.getMetadata();
|
|
@@ -189,7 +189,7 @@ export class StorageInstanceManager {
|
|
|
189
189
|
// we just fetched (so `id`/`name` etc. are available synchronously) along with the backend.
|
|
190
190
|
const instance = new cls({ metadata: storageInfo, backend: subBackend });
|
|
191
191
|
// Atomic cache writes (no awaits between these).
|
|
192
|
-
this
|
|
192
|
+
this.#cache.set(cls, instance, backendCacheKey, alias);
|
|
193
193
|
return instance;
|
|
194
194
|
}
|
|
195
195
|
finally {
|
|
@@ -197,7 +197,7 @@ export class StorageInstanceManager {
|
|
|
197
197
|
// Clean up idle locks so the map doesn't grow unboundedly
|
|
198
198
|
// (mirrors crawlee-python's WeakValueDictionary behaviour).
|
|
199
199
|
if (queue.remaining === 0) {
|
|
200
|
-
this
|
|
200
|
+
this.#openerLocks.delete(lockKey);
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
}
|
|
@@ -205,7 +205,7 @@ export class StorageInstanceManager {
|
|
|
205
205
|
* Remove a storage instance from the cache (called from `storage.drop()`).
|
|
206
206
|
*/
|
|
207
207
|
removeFromCache(instance) {
|
|
208
|
-
this
|
|
208
|
+
this.#cache.removeFromCache(instance);
|
|
209
209
|
}
|
|
210
210
|
/**
|
|
211
211
|
* Clear the entire cache. Also calls `clearCache()` on any cached KeyValueStore
|
|
@@ -213,12 +213,12 @@ export class StorageInstanceManager {
|
|
|
213
213
|
* Called during service locator reset.
|
|
214
214
|
*/
|
|
215
215
|
clearCache() {
|
|
216
|
-
for (const instance of this
|
|
216
|
+
for (const instance of this.#cache.allValues()) {
|
|
217
217
|
if ('clearCache' in instance && typeof instance.clearCache === 'function') {
|
|
218
218
|
instance.clearCache();
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
|
-
this
|
|
221
|
+
this.#cache.clear();
|
|
222
222
|
}
|
|
223
223
|
}
|
|
224
224
|
/**
|
|
@@ -39,7 +39,7 @@ export interface RequestQueueStats {
|
|
|
39
39
|
* the buckets that make sense for it.
|
|
40
40
|
*/
|
|
41
41
|
export declare class StorageStatsTracker<T extends Record<keyof T, number>> {
|
|
42
|
-
private
|
|
42
|
+
#private;
|
|
43
43
|
constructor(initial: T);
|
|
44
44
|
/** Increment a counter bucket by `by` (default `1`). */
|
|
45
45
|
add(key: keyof T, by?: number): void;
|
|
@@ -14,16 +14,16 @@
|
|
|
14
14
|
* the buckets that make sense for it.
|
|
15
15
|
*/
|
|
16
16
|
export class StorageStatsTracker {
|
|
17
|
-
counters;
|
|
17
|
+
#counters;
|
|
18
18
|
constructor(initial) {
|
|
19
|
-
this
|
|
19
|
+
this.#counters = { ...initial };
|
|
20
20
|
}
|
|
21
21
|
/** Increment a counter bucket by `by` (default `1`). */
|
|
22
22
|
add(key, by = 1) {
|
|
23
|
-
this
|
|
23
|
+
this.#counters[key] += by;
|
|
24
24
|
}
|
|
25
25
|
/** Return a snapshot of the current counters. The returned object is a copy and safe to keep. */
|
|
26
26
|
get current() {
|
|
27
|
-
return { ...this
|
|
27
|
+
return { ...this.#counters };
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -142,13 +142,11 @@ export interface StorageTransactionOptions {
|
|
|
142
142
|
* handler unless `transactionalStorage: false` is set.
|
|
143
143
|
*/
|
|
144
144
|
export declare class StorageTransaction implements StorageTransactionView {
|
|
145
|
+
#private;
|
|
145
146
|
/** The ordered, append-only journal — the source of truth for commit, introspection and reads. */
|
|
146
147
|
readonly journal: JournalEntry[];
|
|
147
148
|
/** Per-storage-type write policy. */
|
|
148
149
|
readonly policy: StorageWritePolicy;
|
|
149
|
-
private readonly commitTimeoutMillis;
|
|
150
|
-
private _state;
|
|
151
|
-
private disposed;
|
|
152
150
|
/** @internal */
|
|
153
151
|
constructor(options?: StorageTransactionOptions);
|
|
154
152
|
get state(): StorageTransactionState;
|
package/storages/transaction.js
CHANGED
|
@@ -21,23 +21,23 @@ export class StorageTransaction {
|
|
|
21
21
|
journal = [];
|
|
22
22
|
/** Per-storage-type write policy. */
|
|
23
23
|
policy;
|
|
24
|
-
commitTimeoutMillis;
|
|
25
|
-
|
|
26
|
-
disposed = false;
|
|
24
|
+
#commitTimeoutMillis;
|
|
25
|
+
#state = 'open';
|
|
26
|
+
#disposed = false;
|
|
27
27
|
/** @internal */
|
|
28
28
|
constructor(options = {}) {
|
|
29
29
|
this.policy = { ...DEFAULT_STORAGE_WRITE_POLICY, ...options.policy };
|
|
30
|
-
this
|
|
30
|
+
this.#commitTimeoutMillis = options.commitTimeoutMillis ?? DEFAULT_COMMIT_TIMEOUT_MILLIS;
|
|
31
31
|
}
|
|
32
32
|
get state() {
|
|
33
|
-
return this
|
|
33
|
+
return this.#state;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
36
|
* `true` only while `state === 'open'`. This is the single predicate every storage operation
|
|
37
37
|
* consults — operations performed after the transaction is closed pass through to the real backend.
|
|
38
38
|
*/
|
|
39
39
|
get isActive() {
|
|
40
|
-
return this
|
|
40
|
+
return this.#state === 'open';
|
|
41
41
|
}
|
|
42
42
|
/** Runs `callback` with this transaction installed in the async context. */
|
|
43
43
|
async run(callback) {
|
|
@@ -49,7 +49,7 @@ export class StorageTransaction {
|
|
|
49
49
|
*/
|
|
50
50
|
recordJournalEntry(entry) {
|
|
51
51
|
if (!this.isActive) {
|
|
52
|
-
throw new Error(`Cannot record a journal entry on a transaction in the '${this
|
|
52
|
+
throw new Error(`Cannot record a journal entry on a transaction in the '${this.#state}' state`);
|
|
53
53
|
}
|
|
54
54
|
this.journal.push(entry);
|
|
55
55
|
}
|
|
@@ -62,20 +62,20 @@ export class StorageTransaction {
|
|
|
62
62
|
* partway may have applied some of the writes already.
|
|
63
63
|
*/
|
|
64
64
|
async commit() {
|
|
65
|
-
if (this
|
|
65
|
+
if (this.#state !== 'open') {
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
|
-
this
|
|
68
|
+
this.#state = 'committing';
|
|
69
69
|
try {
|
|
70
70
|
// The replay re-drives the frontend write path, which checks for cancellation (`tryCancel`)
|
|
71
71
|
// on every operation - and `@apify/timeout` shares one `AbortController` across nested
|
|
72
72
|
// frames, so a request-handler timeout that already fired would abort the commit of a
|
|
73
73
|
// handler that succeeded. Hence a fresh timeout context, which also provides the time bound.
|
|
74
|
-
await timeoutStorage.exit(async () => addTimeoutToPromise(async () => this.flush(), this
|
|
75
|
-
this
|
|
74
|
+
await timeoutStorage.exit(async () => addTimeoutToPromise(async () => this.flush(), this.#commitTimeoutMillis, `Committing the storage transaction timed out after ${this.#commitTimeoutMillis / 1000} seconds.`));
|
|
75
|
+
this.#state = 'committed';
|
|
76
76
|
}
|
|
77
77
|
catch (error) {
|
|
78
|
-
this
|
|
78
|
+
this.#state = 'failed';
|
|
79
79
|
throw error;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -106,10 +106,10 @@ export class StorageTransaction {
|
|
|
106
106
|
* and never throws.
|
|
107
107
|
*/
|
|
108
108
|
rollback() {
|
|
109
|
-
if (this
|
|
109
|
+
if (this.#state !== 'open') {
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
|
-
this
|
|
112
|
+
this.#state = 'rolledBack';
|
|
113
113
|
}
|
|
114
114
|
/**
|
|
115
115
|
* Releases the journal and the write-time snapshots it holds. Must be called for *every* terminal
|
|
@@ -117,10 +117,10 @@ export class StorageTransaction {
|
|
|
117
117
|
* {@link StorageTransactionView} of this transaction is only valid until this is called.
|
|
118
118
|
*/
|
|
119
119
|
dispose() {
|
|
120
|
-
if (this
|
|
120
|
+
if (this.#disposed) {
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
|
-
if (this
|
|
123
|
+
if (this.#state === 'open') {
|
|
124
124
|
// Disposing an open transaction is an internal invariant violation - roll back first.
|
|
125
125
|
try {
|
|
126
126
|
serviceLocator
|
|
@@ -132,7 +132,7 @@ export class StorageTransaction {
|
|
|
132
132
|
}
|
|
133
133
|
this.rollback();
|
|
134
134
|
}
|
|
135
|
-
this
|
|
135
|
+
this.#disposed = true;
|
|
136
136
|
this.journal.length = 0;
|
|
137
137
|
}
|
|
138
138
|
get datasetItems() {
|
package/system-info/runtime.js
CHANGED
|
@@ -50,31 +50,31 @@ export async function isContainerized() {
|
|
|
50
50
|
export function isLambda() {
|
|
51
51
|
return !!process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE;
|
|
52
52
|
}
|
|
53
|
-
let
|
|
53
|
+
let cgroupsVersion;
|
|
54
54
|
/**
|
|
55
55
|
* gets the cgroup version by checking for a file at /sys/fs/cgroup/memory
|
|
56
56
|
* @returns "V1" or "V2" for the version of cgroup or null if cgroup is not found.
|
|
57
57
|
*/
|
|
58
58
|
export async function getCgroupsVersion(forceReset) {
|
|
59
59
|
// Parameter forceReset is just internal for unit tests.
|
|
60
|
-
if (
|
|
61
|
-
return
|
|
60
|
+
if (cgroupsVersion !== undefined && !forceReset) {
|
|
61
|
+
return cgroupsVersion;
|
|
62
62
|
}
|
|
63
63
|
try {
|
|
64
64
|
// If this directory does not exists, cgroups are not available
|
|
65
65
|
await fs.access('/sys/fs/cgroup/');
|
|
66
66
|
}
|
|
67
67
|
catch (e) {
|
|
68
|
-
|
|
68
|
+
cgroupsVersion = null;
|
|
69
69
|
return null;
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
cgroupsVersion = 'V1';
|
|
72
72
|
try {
|
|
73
73
|
// If this directory does not exists, assume the container is using cgroups V2
|
|
74
74
|
await fs.access('/sys/fs/cgroup/memory/');
|
|
75
75
|
}
|
|
76
76
|
catch (e) {
|
|
77
|
-
|
|
77
|
+
cgroupsVersion = 'V2';
|
|
78
78
|
}
|
|
79
|
-
return
|
|
79
|
+
return cgroupsVersion;
|
|
80
80
|
}
|