52 lines
1.7 KiB
JavaScript
52 lines
1.7 KiB
JavaScript
import http from 'node:http';
|
|
import { HarborError } from '../shared/errors.js';
|
|
|
|
function request(socketPath, pathname, method = 'GET') {
|
|
return new Promise((resolve, reject) => {
|
|
const req = http.request({ socketPath, path: pathname, method }, (res) => {
|
|
const chunks = [];
|
|
res.on('data', (chunk) => chunks.push(chunk));
|
|
res.on('end', () => {
|
|
let body = {};
|
|
try {
|
|
body = JSON.parse(Buffer.concat(chunks).toString('utf8') || '{}');
|
|
} catch {
|
|
return reject(new Error('Dataplane вернул невалидный JSON'));
|
|
}
|
|
if ((res.statusCode || 500) >= 400) {
|
|
return reject(new Error(body.error || `Dataplane HTTP ${res.statusCode}`));
|
|
}
|
|
resolve(body);
|
|
});
|
|
});
|
|
req.on('error', reject);
|
|
req.setTimeout(6000, () => req.destroy(new Error('Dataplane не ответил за 6 секунд')));
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
export function createDataplaneClient(socketPath, send = request) {
|
|
let current = { running: false, startedAt: null };
|
|
const update = async (pathname, method) => {
|
|
try {
|
|
current = await send(socketPath, pathname, method);
|
|
return current;
|
|
} catch (cause) {
|
|
if (pathname === '/apply' || pathname === '/restart') {
|
|
throw new HarborError('PROCESS_START_FAILED', { cause });
|
|
}
|
|
throw cause;
|
|
}
|
|
};
|
|
|
|
return {
|
|
get running() { return Boolean(current.running); },
|
|
get startedAt() { return current.startedAt || null; },
|
|
refresh: () => update('/status', 'GET'),
|
|
apply: () => update('/apply', 'POST'),
|
|
restart: () => update('/restart', 'POST'),
|
|
stop: () => update('/stop', 'POST'),
|
|
shutdown: async () => current,
|
|
};
|
|
}
|