Ассинхронная обработка запроса с возможностью отмены
Ситуация такая что приходит большой текст который пилится на равные части и обрабатывается через потоки. На фронте запрос можно отменить при помощи abortController и отмена на фронте происходит и запрос прерывается. Пытаюсь отследить событие отмены запроса но не получается, подскажите в чем проблема
import { Injectable, Req } from '@nestjs/common';
import * as workerpool from 'workerpool';
import { cpus } from 'os';
import * as path from 'path';
import { CensorTextDto } from './dto/censor-text.dto';
@Injectable()
export class CensorshipService {
private pool: workerpool.Pool;
constructor() {
this.pool = workerpool.pool(
path.resolve(__dirname, './worker/censorship.worker'),
{
maxWorkers: cpus().length,
},
);
}
async censorText({ text, numWorkers, blackList }: CensorTextDto, @Req() req) {
const filteringText = text.split(' ');
const workerCount = Math.min(numWorkers, cpus().length);
const chunkSize = Math.ceil(filteringText.length / numWorkers);
const chunks = [];
for (let i = 0; i < workerCount; i++) {
const start = i * chunkSize;
const end = Math.min((i + 1) * chunkSize, filteringText.length);
chunks.push(filteringText.slice(start, end).join(' '));
}
try {
const closePromise = new Promise((_, reject) => {
req.on('abort', () => {
this.pool.terminate(true);
reject(new Error('Запрос был отменен'));
});
});
const filteredChunks = await Promise.race([
Promise.all(
chunks.map((chunk) =>
this.pool.exec('filterText', [chunk, blackList]),
),
),
closePromise,
]);
const filteredText = filteredChunks.join(' ');
return filteredText;
} catch (error) {
console.error('Error text:', error);
throw new Error('Error during text filtering');
} finally {
this.pool.terminate();
}
}
}
Ответы (1 шт):
Автор решения: Kamikoto Hero
→ Ссылка
Решил проблему изменив на
req.connection.on('close', () => {
this.pool.terminate(true);
resolve('Запрос был отменен');
});