poe2-bot/src-old/executor/TradeQueue.ts
2026-02-13 01:12:11 -05:00

69 lines
1.9 KiB
TypeScript

import { logger } from '../util/logger.js';
import { sleep, randomDelay } from '../util/sleep.js';
import type { TradeExecutor } from './TradeExecutor.js';
import type { TradeInfo, Config } from '../types.js';
export class TradeQueue {
private queue: TradeInfo[] = [];
private processing = false;
constructor(
private executor: TradeExecutor,
private config: Config,
) {}
enqueue(trade: TradeInfo): void {
// De-duplicate: skip if same item ID already queued
const existingIds = new Set(this.queue.flatMap((t) => t.itemIds));
const newIds = trade.itemIds.filter((id) => !existingIds.has(id));
if (newIds.length === 0) {
logger.info({ itemIds: trade.itemIds }, 'Skipping duplicate trade');
return;
}
const dedupedTrade = { ...trade, itemIds: newIds };
this.queue.push(dedupedTrade);
logger.info(
{ itemIds: newIds, queueLength: this.queue.length },
'Trade enqueued',
);
this.processNext();
}
get length(): number {
return this.queue.length;
}
get isProcessing(): boolean {
return this.processing;
}
private async processNext(): Promise<void> {
if (this.processing || this.queue.length === 0) return;
this.processing = true;
const trade = this.queue.shift()!;
try {
logger.info(
{ searchId: trade.searchId, itemIds: trade.itemIds },
'Processing trade',
);
const success = await this.executor.executeTrade(trade);
if (success) {
logger.info({ itemIds: trade.itemIds }, 'Trade completed successfully');
} else {
logger.warn({ itemIds: trade.itemIds }, 'Trade failed');
}
} catch (err) {
logger.error({ err, itemIds: trade.itemIds }, 'Trade execution error');
}
this.processing = false;
// Delay between trades
await randomDelay(this.config.betweenTradesDelayMs, this.config.betweenTradesDelayMs + 3000);
this.processNext();
}
}