refactor: create dispatcher per request

This commit is contained in:
WebStreamr 2025-09-12 07:30:27 +00:00
parent ffd62a5d16
commit 2f370d1b9c
No known key found for this signature in database
5 changed files with 25 additions and 40 deletions

View file

@ -13,6 +13,7 @@ const config: Config = {
coverageDirectory: '<rootDir>/coverage',
coveragePathIgnorePatterns: [
'/src/controller/',
'/src/utils/dispatcher.ts',
],
coverageProvider: 'babel',
coverageThreshold: {

View file

@ -1,6 +1,3 @@
import { socksDispatcher } from 'fetch-socks';
import { Agent, Dispatcher, interceptors, ProxyAgent, setGlobalDispatcher } from 'undici';
process.env['CACHE_DIR'] = '/dev/null';
jest.mock('randomstring', () => ({
@ -12,20 +9,3 @@ beforeEach(() => {
});
console.log = console.warn = console.error = console.info = console.debug = () => { /* disable in favor of logger */ };
let dispatcher: Dispatcher;
if (process.env['ALL_PROXY']) {
const proxyUrl = new URL(process.env['ALL_PROXY']);
if (proxyUrl.protocol === 'socks5:') {
dispatcher = socksDispatcher({ type: 5, host: proxyUrl.hostname, port: parseInt(proxyUrl.port) }, { allowH2: true });
} else {
dispatcher = new ProxyAgent({ uri: proxyUrl.href, allowH2: true });
}
} else {
dispatcher = new Agent({ allowH2: true });
}
dispatcher.compose(
interceptors.dns(),
interceptors.retry({ maxRetries: 3 }),
);
setGlobalDispatcher(dispatcher);

View file

@ -1,7 +1,5 @@
import { randomUUID } from 'node:crypto';
import express, { NextFunction, Request, Response } from 'express';
import { socksDispatcher } from 'fetch-socks';
import { Agent, Dispatcher, interceptors, ProxyAgent, setGlobalDispatcher } from 'undici';
import winston from 'winston';
import { ConfigureController, ManifestController, StreamController } from './controller';
import { BlockedError, logErrorAndReturnNiceString } from './error';
@ -36,23 +34,6 @@ process.on('unhandledRejection', (reason) => {
logger.error('Unhandled rejection: ', reason);
});
let dispatcher: Dispatcher;
if (process.env['ALL_PROXY']) {
const proxyUrl = new URL(process.env['ALL_PROXY']);
if (proxyUrl.protocol === 'socks5:') {
dispatcher = socksDispatcher({ type: 5, host: proxyUrl.hostname, port: parseInt(proxyUrl.port) }, { allowH2: true });
} else {
dispatcher = new ProxyAgent({ uri: proxyUrl.href, allowH2: true });
}
} else {
dispatcher = new Agent({ allowH2: true });
}
dispatcher.compose(
interceptors.dns(),
interceptors.retry({ maxRetries: 3 }),
);
setGlobalDispatcher(dispatcher);
const fetcher = new Fetcher(logger);
const sources = createSources(fetcher);

View file

@ -6,6 +6,7 @@ import { Cookie, CookieJar } from 'tough-cookie';
import winston from 'winston';
import { BlockedError, HttpError, NotFoundError, QueueIsFullError, TimeoutError, TooManyRequestsError, TooManyTimeoutsError } from '../error';
import { BlockedReason, Context } from '../types';
import { createDispatcher } from './dispatcher';
import { envGet } from './env';
interface HttpCacheItem {
@ -282,7 +283,7 @@ export class Fetcher {
finalUrl.username = '';
finalUrl.password = '';
const finalInit = { ...init, keepalive: true, signal: controller.signal };
const finalInit = { ...init, keepalive: true, signal: controller.signal, dispatcher: createDispatcher() };
response = await fetch(finalUrl, finalInit);
} catch (error) {

22
src/utils/dispatcher.ts Normal file
View file

@ -0,0 +1,22 @@
import { socksDispatcher } from 'fetch-socks';
import { Agent, Dispatcher, interceptors, ProxyAgent } from 'undici';
const createBasicDispatcher = (): Dispatcher => {
if (process.env['ALL_PROXY']) {
const proxyUrl = new URL(process.env['ALL_PROXY']);
if (proxyUrl.protocol === 'socks5:') {
return socksDispatcher({ type: 5, host: proxyUrl.hostname, port: parseInt(proxyUrl.port) }, { allowH2: true });
} else {
return new ProxyAgent({ uri: proxyUrl.href, allowH2: true });
}
} else {
return new Agent({ allowH2: true });
}
};
export const createDispatcher = (): Dispatcher => {
return createBasicDispatcher().compose(
interceptors.dns(),
interceptors.retry({ maxRetries: 3 }),
);
};