mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-09 21:17:03 +03:00
♻️ refactor(podkop): update command scheduling and priority handling
This commit is contained in:
@@ -72,20 +72,20 @@ const FETCH_TIMEOUT = 10000; // 10 seconds
|
|||||||
const BUTTON_FEEDBACK_TIMEOUT = 1000; // 1 second
|
const BUTTON_FEEDBACK_TIMEOUT = 1000; // 1 second
|
||||||
const DIAGNOSTICS_INITIAL_DELAY = 100; // 100 milliseconds
|
const DIAGNOSTICS_INITIAL_DELAY = 100; // 100 milliseconds
|
||||||
|
|
||||||
// Массив задержек для приоритетов выполнения команд в диагностике (в миллисекундах)
|
// Интервалы планирования команд в диагностике (в миллисекундах)
|
||||||
const RUN_PRIORITY = [
|
const COMMAND_SCHEDULING = {
|
||||||
0, // Приоритет 0 - Критический (выполняется немедленно)
|
P0_PRIORITY: 0, // Наивысший приоритет (без задержки)
|
||||||
100, // Приоритет 1 - Очень высокий
|
P1_PRIORITY: 100, // Очень высокий приоритет
|
||||||
300, // Приоритет 2 - Высокий
|
P2_PRIORITY: 300, // Высокий приоритет
|
||||||
500, // Приоритет 3 - Выше среднего
|
P3_PRIORITY: 500, // Выше среднего
|
||||||
700, // Приоритет 4 - Средний
|
P4_PRIORITY: 700, // Стандартный приоритет
|
||||||
900, // Приоритет 5 - Ниже среднего
|
P5_PRIORITY: 900, // Ниже среднего
|
||||||
1100, // Приоритет 6 - Низкий
|
P6_PRIORITY: 1100, // Низкий приоритет
|
||||||
1300, // Приоритет 7 - Очень низкий
|
P7_PRIORITY: 1300, // Очень низкий приоритет
|
||||||
1500, // Приоритет 8 - Фоновый
|
P8_PRIORITY: 1500, // Фоновое выполнение
|
||||||
1700, // Приоритет 9 - Отложенный
|
P9_PRIORITY: 1700, // Выполнение в режиме простоя
|
||||||
1900 // Приоритет 10 - Наименее важный
|
P10_PRIORITY: 1900 // Наименьший приоритет
|
||||||
];
|
};
|
||||||
|
|
||||||
return baseclass.extend({
|
return baseclass.extend({
|
||||||
STATUS_COLORS,
|
STATUS_COLORS,
|
||||||
@@ -102,6 +102,6 @@ return baseclass.extend({
|
|||||||
FETCH_TIMEOUT,
|
FETCH_TIMEOUT,
|
||||||
BUTTON_FEEDBACK_TIMEOUT,
|
BUTTON_FEEDBACK_TIMEOUT,
|
||||||
DIAGNOSTICS_INITIAL_DELAY,
|
DIAGNOSTICS_INITIAL_DELAY,
|
||||||
RUN_PRIORITY,
|
COMMAND_SCHEDULING,
|
||||||
CACHE_TIMEOUT
|
CACHE_TIMEOUT
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -44,7 +44,13 @@ function safeExec(command, args, priority, callback, timeout = constants.COMMAND
|
|||||||
|
|
||||||
// Helper functions for handling checks
|
// Helper functions for handling checks
|
||||||
function runCheck(checkFunction, priority, callback) {
|
function runCheck(checkFunction, priority, callback) {
|
||||||
priority = (typeof priority === 'number') ? priority : 0;
|
// Default to highest priority execution if priority is not provided or invalid
|
||||||
|
let schedulingDelay = constants.COMMAND_SCHEDULING.P0_PRIORITY;
|
||||||
|
|
||||||
|
// If priority is a string, try to get the corresponding delay value
|
||||||
|
if (typeof priority === 'string' && constants.COMMAND_SCHEDULING[priority] !== undefined) {
|
||||||
|
schedulingDelay = constants.COMMAND_SCHEDULING[priority];
|
||||||
|
}
|
||||||
|
|
||||||
const executeCheck = async () => {
|
const executeCheck = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -62,7 +68,7 @@ function runCheck(checkFunction, priority, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (callback && typeof callback === 'function') {
|
if (callback && typeof callback === 'function') {
|
||||||
setTimeout(executeCheck, constants.RUN_PRIORITY[priority]);
|
setTimeout(executeCheck, schedulingDelay);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return executeCheck();
|
return executeCheck();
|
||||||
@@ -70,7 +76,13 @@ function runCheck(checkFunction, priority, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function runAsyncTask(taskFunction, priority) {
|
function runAsyncTask(taskFunction, priority) {
|
||||||
priority = (typeof priority === 'number') ? priority : 0;
|
// Default to highest priority execution if priority is not provided or invalid
|
||||||
|
let schedulingDelay = constants.COMMAND_SCHEDULING.P0_PRIORITY;
|
||||||
|
|
||||||
|
// If priority is a string, try to get the corresponding delay value
|
||||||
|
if (typeof priority === 'string' && constants.COMMAND_SCHEDULING[priority] !== undefined) {
|
||||||
|
schedulingDelay = constants.COMMAND_SCHEDULING[priority];
|
||||||
|
}
|
||||||
|
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
@@ -78,7 +90,7 @@ function runAsyncTask(taskFunction, priority) {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Async task error:', error);
|
console.error('Async task error:', error);
|
||||||
}
|
}
|
||||||
}, constants.RUN_PRIORITY[priority]);
|
}, schedulingDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper Functions for UI and formatting
|
// Helper Functions for UI and formatting
|
||||||
@@ -151,21 +163,12 @@ async function checkFakeIP() {
|
|||||||
async function checkFakeIPCLI() {
|
async function checkFakeIPCLI() {
|
||||||
try {
|
try {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
safeExec('/usr/bin/podkop', ['get_sing_box_status'], 0, singboxStatusResult => {
|
safeExec('nslookup', ['-timeout=2', constants.FAKEIP_CHECK_DOMAIN, '127.0.0.42'], 'P0_PRIORITY', result => {
|
||||||
const singboxStatus = JSON.parse(singboxStatusResult.stdout || '{"running":0,"dns_configured":0}');
|
if (result.stdout && result.stdout.includes('198.18')) {
|
||||||
|
resolve(createStatus('working', 'working on router', 'SUCCESS'));
|
||||||
if (!singboxStatus.running) {
|
} else {
|
||||||
resolve(createStatus('not_working', 'sing-box not running', 'ERROR'));
|
resolve(createStatus('not_working', 'not working on router', 'ERROR'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
safeExec('nslookup', ['-timeout=2', constants.FAKEIP_CHECK_DOMAIN, '127.0.0.42'], 0, result => {
|
|
||||||
if (result.stdout && result.stdout.includes('198.18')) {
|
|
||||||
resolve(createStatus('working', 'working on router', 'SUCCESS'));
|
|
||||||
} else {
|
|
||||||
resolve(createStatus('not_working', 'not working on router', 'ERROR'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -176,7 +179,7 @@ async function checkFakeIPCLI() {
|
|||||||
function checkDNSAvailability() {
|
function checkDNSAvailability() {
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
try {
|
try {
|
||||||
safeExec('/usr/bin/podkop', ['check_dns_available'], 0, dnsStatusResult => {
|
safeExec('/usr/bin/podkop', ['check_dns_available'], 'P0_PRIORITY', dnsStatusResult => {
|
||||||
if (!dnsStatusResult || !dnsStatusResult.stdout) {
|
if (!dnsStatusResult || !dnsStatusResult.stdout) {
|
||||||
return resolve({
|
return resolve({
|
||||||
remote: createStatus('error', 'DNS check timeout', 'WARNING'),
|
remote: createStatus('error', 'DNS check timeout', 'WARNING'),
|
||||||
@@ -319,7 +322,7 @@ function showConfigModal(command, title) {
|
|||||||
let formattedOutput = '';
|
let formattedOutput = '';
|
||||||
|
|
||||||
if (command === 'global_check') {
|
if (command === 'global_check') {
|
||||||
safeExec('/usr/bin/podkop', [command], 0, res => {
|
safeExec('/usr/bin/podkop', [command], 'P0_PRIORITY', res => {
|
||||||
formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
|
formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -381,7 +384,7 @@ function showConfigModal(command, title) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
safeExec('/usr/bin/podkop', [command], 0, res => {
|
safeExec('/usr/bin/podkop', [command], 'P0_PRIORITY', res => {
|
||||||
formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
|
formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
|
||||||
updateModalContent(formattedOutput);
|
updateModalContent(formattedOutput);
|
||||||
});
|
});
|
||||||
@@ -405,7 +408,7 @@ const ButtonFactory = {
|
|||||||
return this.createButton({
|
return this.createButton({
|
||||||
label: config.label,
|
label: config.label,
|
||||||
additionalClass: `cbi-button-${config.type || ''}`,
|
additionalClass: `cbi-button-${config.type || ''}`,
|
||||||
onClick: () => safeExec('/usr/bin/podkop', [config.action])
|
onClick: () => safeExec('/usr/bin/podkop', [config.action], 'P0_PRIORITY')
|
||||||
.then(() => config.reload && location.reload()),
|
.then(() => config.reload && location.reload()),
|
||||||
style: config.style
|
style: config.style
|
||||||
});
|
});
|
||||||
@@ -415,7 +418,7 @@ const ButtonFactory = {
|
|||||||
return this.createButton({
|
return this.createButton({
|
||||||
label: config.label,
|
label: config.label,
|
||||||
additionalClass: `cbi-button-${config.type || ''}`,
|
additionalClass: `cbi-button-${config.type || ''}`,
|
||||||
onClick: () => safeExec('/etc/init.d/podkop', [config.action])
|
onClick: () => safeExec('/etc/init.d/podkop', [config.action], 'P0_PRIORITY')
|
||||||
.then(() => config.reload && location.reload()),
|
.then(() => config.reload && location.reload()),
|
||||||
style: config.style
|
style: config.style
|
||||||
});
|
});
|
||||||
@@ -620,7 +623,7 @@ function updateTextElement(elementId, content) {
|
|||||||
|
|
||||||
async function updateDiagnostics() {
|
async function updateDiagnostics() {
|
||||||
// Podkop Status check
|
// Podkop Status check
|
||||||
safeExec('/usr/bin/podkop', ['get_status'], 0, result => {
|
safeExec('/usr/bin/podkop', ['get_status'], 'P0_PRIORITY', result => {
|
||||||
try {
|
try {
|
||||||
const parsedPodkopStatus = JSON.parse(result.stdout || '{"enabled":0,"status":"error"}');
|
const parsedPodkopStatus = JSON.parse(result.stdout || '{"enabled":0,"status":"error"}');
|
||||||
|
|
||||||
@@ -664,7 +667,7 @@ async function updateDiagnostics() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Sing-box Status check
|
// Sing-box Status check
|
||||||
safeExec('/usr/bin/podkop', ['get_sing_box_status'], 0, result => {
|
safeExec('/usr/bin/podkop', ['get_sing_box_status'], 'P0_PRIORITY', result => {
|
||||||
try {
|
try {
|
||||||
const parsedSingboxStatus = JSON.parse(result.stdout || '{"running":0,"enabled":0,"status":"error"}');
|
const parsedSingboxStatus = JSON.parse(result.stdout || '{"running":0,"enabled":0,"status":"error"}');
|
||||||
|
|
||||||
@@ -686,25 +689,25 @@ async function updateDiagnostics() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Version Information checks
|
// Version Information checks
|
||||||
safeExec('/usr/bin/podkop', ['show_version'], 2, result => {
|
safeExec('/usr/bin/podkop', ['show_version'], 'P2_PRIORITY', result => {
|
||||||
updateTextElement('podkop-version',
|
updateTextElement('podkop-version',
|
||||||
document.createTextNode(result.stdout ? result.stdout.trim() : _('Unknown'))
|
document.createTextNode(result.stdout ? result.stdout.trim() : _('Unknown'))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
safeExec('/usr/bin/podkop', ['show_luci_version'], 2, result => {
|
safeExec('/usr/bin/podkop', ['show_luci_version'], 'P2_PRIORITY', result => {
|
||||||
updateTextElement('luci-version',
|
updateTextElement('luci-version',
|
||||||
document.createTextNode(result.stdout ? result.stdout.trim() : _('Unknown'))
|
document.createTextNode(result.stdout ? result.stdout.trim() : _('Unknown'))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
safeExec('/usr/bin/podkop', ['show_sing_box_version'], 2, result => {
|
safeExec('/usr/bin/podkop', ['show_sing_box_version'], 'P2_PRIORITY', result => {
|
||||||
updateTextElement('singbox-version',
|
updateTextElement('singbox-version',
|
||||||
document.createTextNode(result.stdout ? result.stdout.trim() : _('Unknown'))
|
document.createTextNode(result.stdout ? result.stdout.trim() : _('Unknown'))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
safeExec('/usr/bin/podkop', ['show_system_info'], 2, result => {
|
safeExec('/usr/bin/podkop', ['show_system_info'], 'P2_PRIORITY', result => {
|
||||||
if (result.stdout) {
|
if (result.stdout) {
|
||||||
updateTextElement('openwrt-version',
|
updateTextElement('openwrt-version',
|
||||||
document.createTextNode(result.stdout.split('\n')[1].trim())
|
document.createTextNode(result.stdout.split('\n')[1].trim())
|
||||||
@@ -719,7 +722,7 @@ async function updateDiagnostics() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// FakeIP and DNS status checks
|
// FakeIP and DNS status checks
|
||||||
runCheck(checkFakeIP, 3, result => {
|
runCheck(checkFakeIP, 'P3_PRIORITY', result => {
|
||||||
updateTextElement('fakeip-browser-status',
|
updateTextElement('fakeip-browser-status',
|
||||||
E('span', { style: `color: ${result.error ? constants.STATUS_COLORS.WARNING : result.color}` }, [
|
E('span', { style: `color: ${result.error ? constants.STATUS_COLORS.WARNING : result.color}` }, [
|
||||||
result.error ? '! ' : result.state === 'working' ? '✔ ' : result.state === 'not_working' ? '✘ ' : '! ',
|
result.error ? '! ' : result.state === 'working' ? '✔ ' : result.state === 'not_working' ? '✘ ' : '! ',
|
||||||
@@ -728,7 +731,7 @@ async function updateDiagnostics() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
runCheck(checkFakeIPCLI, 3, result => {
|
runCheck(checkFakeIPCLI, 'P8_PRIORITY', result => {
|
||||||
updateTextElement('fakeip-router-status',
|
updateTextElement('fakeip-router-status',
|
||||||
E('span', { style: `color: ${result.error ? constants.STATUS_COLORS.WARNING : result.color}` }, [
|
E('span', { style: `color: ${result.error ? constants.STATUS_COLORS.WARNING : result.color}` }, [
|
||||||
result.error ? '! ' : result.state === 'working' ? '✔ ' : result.state === 'not_working' ? '✘ ' : '! ',
|
result.error ? '! ' : result.state === 'working' ? '✔ ' : result.state === 'not_working' ? '✘ ' : '! ',
|
||||||
@@ -737,7 +740,7 @@ async function updateDiagnostics() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
runCheck(checkDNSAvailability, 4, result => {
|
runCheck(checkDNSAvailability, 'P4_PRIORITY', result => {
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
updateTextElement('dns-remote-status',
|
updateTextElement('dns-remote-status',
|
||||||
E('span', { style: `color: ${constants.STATUS_COLORS.WARNING}` }, '! DNS check error')
|
E('span', { style: `color: ${constants.STATUS_COLORS.WARNING}` }, '! DNS check error')
|
||||||
@@ -762,14 +765,14 @@ async function updateDiagnostics() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
runCheck(checkBypass, 1, result => {
|
runCheck(checkBypass, 'P1_PRIORITY', result => {
|
||||||
updateTextElement('bypass-status',
|
updateTextElement('bypass-status',
|
||||||
E('span', { style: `color: ${result.error ? constants.STATUS_COLORS.WARNING : result.color}` }, [
|
E('span', { style: `color: ${result.error ? constants.STATUS_COLORS.WARNING : result.color}` }, [
|
||||||
result.error ? '! ' : result.state === 'working' ? '✔ ' : result.state === 'not_working' ? '✘ ' : '! ',
|
result.error ? '! ' : result.state === 'working' ? '✔ ' : result.state === 'not_working' ? '✘ ' : '! ',
|
||||||
result.error ? 'check error' : result.message
|
result.error ? 'check error' : result.message
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
});
|
}, 'P1_PRIORITY');
|
||||||
|
|
||||||
// Config name
|
// Config name
|
||||||
runAsyncTask(async () => {
|
runAsyncTask(async () => {
|
||||||
@@ -797,7 +800,7 @@ async function updateDiagnostics() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error getting config name from UCI:', e);
|
console.error('Error getting config name from UCI:', e);
|
||||||
}
|
}
|
||||||
}, 1);
|
}, 'P1_PRIORITY');
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDiagnosticsSection(mainSection) {
|
function createDiagnosticsSection(mainSection) {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ let errorPollTimer = null;
|
|||||||
// Helper function to fetch errors from the podkop command
|
// Helper function to fetch errors from the podkop command
|
||||||
async function getPodkopErrors() {
|
async function getPodkopErrors() {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
safeExec('/usr/bin/podkop', ['check_logs'], 0, result => {
|
safeExec('/usr/bin/podkop', ['check_logs'], 'P0_PRIORITY', result => {
|
||||||
if (!result || !result.stdout) return resolve([]);
|
if (!result || !result.stdout) return resolve([]);
|
||||||
|
|
||||||
const logs = result.stdout.split('\n');
|
const logs = result.stdout.split('\n');
|
||||||
@@ -40,7 +40,13 @@ function showErrorNotification(error, isMultiple = false) {
|
|||||||
|
|
||||||
// Helper function for command execution with prioritization
|
// Helper function for command execution with prioritization
|
||||||
function safeExec(command, args, priority, callback, timeout = constants.COMMAND_TIMEOUT) {
|
function safeExec(command, args, priority, callback, timeout = constants.COMMAND_TIMEOUT) {
|
||||||
priority = (typeof priority === 'number') ? priority : 0;
|
// Default to highest priority execution if priority is not provided or invalid
|
||||||
|
let schedulingDelay = constants.COMMAND_SCHEDULING.P0_PRIORITY;
|
||||||
|
|
||||||
|
// If priority is a string, try to get the corresponding delay value
|
||||||
|
if (typeof priority === 'string' && constants.COMMAND_SCHEDULING[priority] !== undefined) {
|
||||||
|
schedulingDelay = constants.COMMAND_SCHEDULING[priority];
|
||||||
|
}
|
||||||
|
|
||||||
const executeCommand = async () => {
|
const executeCommand = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -76,7 +82,7 @@ function safeExec(command, args, priority, callback, timeout = constants.COMMAND
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (callback && typeof callback === 'function') {
|
if (callback && typeof callback === 'function') {
|
||||||
setTimeout(executeCommand, constants.RUN_PRIORITY[priority]);
|
setTimeout(executeCommand, schedulingDelay);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
Reference in New Issue
Block a user