refactor: Phase 1 code cleanup - constants, logging, and repository organization

This commit is contained in:
2026-03-28 18:54:39 -07:00
parent f1b0ac43d0
commit 6c3848102b
24 changed files with 17078 additions and 50 deletions

View File

@@ -37,29 +37,35 @@ module.exports = function(ctx) {
return resolveServiceUrl(id, service, ctx.siteConfig, ctx.buildServiceUrl);
}
const PROBE_TIMEOUT = 3000; // 3s — covers DNS + connect + response
function requestStatusCode(url, method) {
const parsed = new URL(url);
const isHttps = parsed.protocol === 'https:';
const lib = isHttps ? https : http;
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
req.destroy();
reject(new Error('Timeout'));
}, PROBE_TIMEOUT);
const req = lib.request({
hostname: parsed.hostname,
port: parsed.port || (isHttps ? 443 : 80),
path: parsed.pathname + parsed.search,
method,
timeout: TIMEOUTS.HTTP_DEFAULT,
agent: isHttps ? probeHttpsAgent : undefined,
headers: { 'User-Agent': APP.USER_AGENTS.PROBE },
}, (response) => {
clearTimeout(timer);
response.resume();
resolve(response.statusCode || 0);
});
req.on('error', reject);
req.on('timeout', () => {
req.destroy();
reject(new Error('Timeout'));
req.on('error', (err) => {
clearTimeout(timer);
reject(err);
});
req.end();
});
@@ -73,7 +79,7 @@ module.exports = function(ctx) {
const headers = {};
if (pylonConfig.key) headers['x-pylon-key'] = pylonConfig.key;
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 12000);
const timeout = setTimeout(() => controller.abort(), 5000);
const response = await ctx.fetchT(probeUrl, { method: 'GET', signal: controller.signal, headers });
clearTimeout(timeout);
if (!response.ok) return null;
@@ -86,7 +92,7 @@ module.exports = function(ctx) {
async function probeServiceStatus(id, service) {
const startedAt = process.hrtime.bigint();
let url = resolveProbeUrl(id, service);
const url = resolveProbeUrl(id, service);
let statusCode = 502;
let error = null;
@@ -97,21 +103,9 @@ module.exports = function(ctx) {
}
} catch (primaryError) {
error = primaryError;
if (id !== 'internet') {
const fallbackUrl = ctx.buildServiceUrl(id);
if (fallbackUrl !== url) {
try {
statusCode = await requestStatusCode(fallbackUrl, 'GET');
url = fallbackUrl;
error = null;
} catch (fallbackError) {
error = fallbackError;
}
}
}
}
// Pylon relay fallback — if direct probes failed, try through the pylon
// Pylon relay fallback — if direct probe failed, try through the pylon
if (error && ctx.siteConfig?.pylon) {
const pylonResult = await probeViaPylon(url);
if (pylonResult && pylonResult.status) {
@@ -267,6 +261,8 @@ module.exports = function(ctx) {
// ===== SERVICE CRUD ENDPOINTS =====
// Batched live status for dashboard cards
const STATUS_DEADLINE = 10000; // 10s — return whatever we have by then
router.get('/services/status', ctx.asyncHandler(async (req, res) => {
const services = await loadServicesList();
const serviceMap = new Map(services.filter(s => s && s.id).map(s => [s.id, s]));
@@ -283,19 +279,31 @@ module.exports = function(ctx) {
Object.keys(ctx.siteConfig?.dnsServers || {}).forEach(addId);
services.forEach(service => addId(service.id));
const statusResults = await mapWithConcurrency(ids, PROBE_CONCURRENCY, (id) =>
probeServiceStatus(id, serviceMap.get(id))
);
// Collect results as they arrive; deadline returns whatever we have
const statuses = {};
statusResults.forEach((result) => {
const probeWork = mapWithConcurrency(ids, PROBE_CONCURRENCY, async (id) => {
const result = await probeServiceStatus(id, serviceMap.get(id));
statuses[result.id] = result;
return result;
});
const deadline = new Promise((resolve) =>
setTimeout(() => resolve(null), STATUS_DEADLINE)
);
await Promise.race([probeWork, deadline]);
// Fill any IDs that didn't finish before the deadline
const partial = ids.some((id) => !statuses[id]);
ids.forEach((id) => {
if (!statuses[id]) {
statuses[id] = { id, isUp: false, statusCode: 0, responseTime: STATUS_DEADLINE, error: 'deadline' };
}
});
res.set('Cache-Control', 'no-store');
res.json({
success: true,
checkedAt: new Date().toISOString(),
partial,
statuses
});
}, 'services-status'));