|
|
@@ -4,6 +4,7 @@ import type { Order, OrderBook } from "../../domain/src/types";
|
|
|
export interface OrderRouterConfig {
|
|
|
maxBps: number;
|
|
|
minIntervalMs?: number;
|
|
|
+ bulkInitIntervalMs?: number;
|
|
|
forbidPostOnlyCross?: boolean;
|
|
|
clientIdCacheSize?: number;
|
|
|
}
|
|
|
@@ -18,10 +19,12 @@ export type CancelClientFn = (clientId: string) => Promise<void>;
|
|
|
|
|
|
export class OrderRouter {
|
|
|
private readonly minIntervalMs: number;
|
|
|
+ private readonly bulkInitIntervalMs: number;
|
|
|
private readonly forbidPostOnlyCross: boolean;
|
|
|
private readonly maxBps: number;
|
|
|
private readonly clientIdCacheSize: number;
|
|
|
private lastSendAt = 0;
|
|
|
+ private bulkInitMode = false;
|
|
|
private readonly recentClientIds: string[] = [];
|
|
|
private readonly clientIdSet = new Set<string>();
|
|
|
private readonly clientIdAlias = new Map<string, string>();
|
|
|
@@ -35,10 +38,19 @@ export class OrderRouter {
|
|
|
) {
|
|
|
this.maxBps = config.maxBps;
|
|
|
this.minIntervalMs = config.minIntervalMs ?? 0;
|
|
|
+ this.bulkInitIntervalMs = config.bulkInitIntervalMs ?? Math.min(20, this.minIntervalMs);
|
|
|
this.forbidPostOnlyCross = config.forbidPostOnlyCross ?? true;
|
|
|
this.clientIdCacheSize = config.clientIdCacheSize ?? 512;
|
|
|
}
|
|
|
|
|
|
+ enableBulkInitMode(): void {
|
|
|
+ this.bulkInitMode = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ disableBulkInitMode(): void {
|
|
|
+ this.bulkInitMode = false;
|
|
|
+ }
|
|
|
+
|
|
|
async sendLimit(order: Order): Promise<string> {
|
|
|
order.clientId = this.normalizeClientId(order.clientId);
|
|
|
await this.ensureThrottle();
|
|
|
@@ -115,11 +127,12 @@ export class OrderRouter {
|
|
|
}
|
|
|
|
|
|
private async ensureThrottle() {
|
|
|
- if (this.minIntervalMs <= 0) return;
|
|
|
+ const intervalMs = this.bulkInitMode ? this.bulkInitIntervalMs : this.minIntervalMs;
|
|
|
+ if (intervalMs <= 0) return;
|
|
|
const now = Date.now();
|
|
|
const elapsed = now - this.lastSendAt;
|
|
|
- if (elapsed < this.minIntervalMs) {
|
|
|
- await new Promise(resolve => setTimeout(resolve, this.minIntervalMs - elapsed));
|
|
|
+ if (elapsed < intervalMs) {
|
|
|
+ await new Promise(resolve => setTimeout(resolve, intervalMs - elapsed));
|
|
|
}
|
|
|
this.lastSendAt = Date.now();
|
|
|
}
|