fix(dlob-worker): allow forcing IPv6 egress
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import fs from 'node:fs';
|
||||
import * as http from 'node:http';
|
||||
import * as https from 'node:https';
|
||||
import process from 'node:process';
|
||||
import { setTimeout as sleep } from 'node:timers/promises';
|
||||
|
||||
@@ -29,6 +31,15 @@ function envList(name, fallbackCsv) {
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
function envBool(name, fallback = false) {
|
||||
const raw = process.env[name];
|
||||
if (raw == null) return fallback;
|
||||
const v = String(raw).trim().toLowerCase();
|
||||
if (['1', 'true', 'yes', 'y', 'on'].includes(v)) return true;
|
||||
if (['0', 'false', 'no', 'n', 'off'].includes(v)) return false;
|
||||
return fallback;
|
||||
}
|
||||
|
||||
function resolveConfig() {
|
||||
const tokensPath =
|
||||
process.env.HASURA_TOKENS_FILE ||
|
||||
@@ -52,6 +63,7 @@ function resolveConfig() {
|
||||
const dlobHttpBase = String(process.env.DLOB_HTTP_URL || process.env.DLOB_HTTP_BASE || 'https://dlob.drift.trade')
|
||||
.trim()
|
||||
.replace(/\/$/, '');
|
||||
const dlobForceIpv6 = envBool('DLOB_FORCE_IPV6', false);
|
||||
|
||||
const markets = envList('DLOB_MARKETS', 'PUMP-PERP,SOL-PERP,1MBONK-PERP,BTC-PERP,ETH-PERP');
|
||||
const depth = clampInt(process.env.DLOB_DEPTH, 1, 50, 10);
|
||||
@@ -69,6 +81,7 @@ function resolveConfig() {
|
||||
hasuraAdminSecret,
|
||||
hasuraAuthToken,
|
||||
dlobHttpBase,
|
||||
dlobForceIpv6,
|
||||
markets,
|
||||
depth,
|
||||
pollMs,
|
||||
@@ -77,6 +90,47 @@ function resolveConfig() {
|
||||
};
|
||||
}
|
||||
|
||||
async function requestText(url, { timeoutMs, family } = {}) {
|
||||
const u = new URL(url);
|
||||
const client = u.protocol === 'https:' ? https : http;
|
||||
|
||||
const port = u.port ? Number.parseInt(u.port, 10) : u.protocol === 'https:' ? 443 : 80;
|
||||
if (!Number.isFinite(port)) throw new Error(`Invalid port for url: ${url}`);
|
||||
|
||||
return await new Promise((resolve, reject) => {
|
||||
const req = client.request(
|
||||
{
|
||||
protocol: u.protocol,
|
||||
hostname: u.hostname,
|
||||
port,
|
||||
path: `${u.pathname}${u.search}`,
|
||||
method: 'GET',
|
||||
family,
|
||||
servername: u.hostname,
|
||||
headers: {
|
||||
accept: 'application/json',
|
||||
},
|
||||
},
|
||||
(res) => {
|
||||
let data = '';
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
res.on('end', () => {
|
||||
resolve({ status: res.statusCode ?? 0, text: data });
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
req.on('error', reject);
|
||||
req.setTimeout(timeoutMs ?? 5_000, () => {
|
||||
req.destroy(new Error(`Timeout after ${timeoutMs ?? 5_000}ms`));
|
||||
});
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
async function graphqlRequest(cfg, query, variables) {
|
||||
const headers = { 'content-type': 'application/json' };
|
||||
if (cfg.hasuraAuthToken) {
|
||||
@@ -234,7 +288,15 @@ async function fetchL2(cfg, marketName) {
|
||||
const u = new URL(`${cfg.dlobHttpBase}/l2`);
|
||||
u.searchParams.set('marketName', marketName);
|
||||
u.searchParams.set('depth', String(cfg.depth));
|
||||
const res = await fetch(u.toString(), { signal: AbortSignal.timeout(5_000) });
|
||||
|
||||
const url = u.toString();
|
||||
if (cfg.dlobForceIpv6) {
|
||||
const { status, text } = await requestText(url, { timeoutMs: 5_000, family: 6 });
|
||||
if (status < 200 || status >= 300) throw new Error(`DLOB HTTP ${status}: ${text}`);
|
||||
return JSON.parse(text);
|
||||
}
|
||||
|
||||
const res = await fetch(url, { signal: AbortSignal.timeout(5_000) });
|
||||
const text = await res.text();
|
||||
if (!res.ok) throw new Error(`DLOB HTTP ${res.status}: ${text}`);
|
||||
return JSON.parse(text);
|
||||
@@ -310,6 +372,7 @@ async function main() {
|
||||
hasuraUrl: cfg.hasuraUrl,
|
||||
hasuraAuth: cfg.hasuraAuthToken ? 'bearer' : cfg.hasuraAdminSecret ? 'admin-secret' : 'none',
|
||||
dlobHttpBase: cfg.dlobHttpBase,
|
||||
dlobForceIpv6: cfg.dlobForceIpv6,
|
||||
markets: cfg.markets,
|
||||
depth: cfg.depth,
|
||||
pollMs: cfg.pollMs,
|
||||
|
||||
Reference in New Issue
Block a user