From 93767073be16946b5f0e7a8458d621ad8fe376ab Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sat, 9 Aug 2025 22:02:42 -0400 Subject: [PATCH 01/15] Refactor: Switch docker_load from bash to php --- .../dynamix.docker.manager/nchan/docker_load | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load index a0a7e9c9f..11271704f 100755 --- a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load +++ b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load @@ -1,13 +1,29 @@ -#!/bin/bash +#!/usr/bin/php -q + +&1) - if [[ $? -ne 0 ]]; then - logger -t webgui "docker stats error: $output" - exit 1 - fi - if [[ -n "$output" ]]; then - curl -sfd "$output" --unix-socket /var/run/nginx.socket http://localhost/pub/dockerload?buffer_length=1 >/dev/null 2>&1 - fi - sleep 1 -done +require_once "$docroot/webGui/include/Helpers.php"; +require_once "$docroot/webGui/include/publish.php"; + +while (true) { + $output = shell_exec("docker stats --no-stream --format='{{.ID}};{{.CPUPerc}};{{.MemUsage}}'"); + if ($output === false) { + my_logger("docker stats error: $output"); + exit(1); + } + // publish and exit the script if no listeners after 120 seconds + publish("dockerload", $output, 1, true, 120); + sleep(1); +} From 5e7fe097f4c33836aa8b9556004eb212e71216f0 Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sat, 9 Aug 2025 22:05:08 -0400 Subject: [PATCH 02/15] Refactor: Allow publish to exit if no listeners --- emhttp/plugins/dynamix/include/publish.php | 52 +++++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/emhttp/plugins/dynamix/include/publish.php b/emhttp/plugins/dynamix/include/publish.php index 701fcb71a..34e085f74 100644 --- a/emhttp/plugins/dynamix/include/publish.php +++ b/emhttp/plugins/dynamix/include/publish.php @@ -1,5 +1,5 @@ $abortTime) { + my_logger("$endpoint timed out after $abortTime seconds. Exiting.", 'publish'); + + removeNChanScript(); + exit(); + } + } else { + // a subscriber is present. Reset the abort timer if it's set + $abortStart[$endpoint] = null; + } + } return $reply; } + +// Removes the script calling this function from nchan.pid +function removeNChanScript() { + global $docroot, $argv; + + $script = str_replace("$docroot/","",(php_sapi_name() === 'cli') ? $argv[0] : $_SERVER['argv'][0]); + $nchan = @file("/var/run/nchan.pid",FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: []; + $nchan = array_filter($nchan,function($x) use ($script) { + return $script !== trim(explode(":",$x)[0]); + }); + + if (count($nchan) > 0) { + file_put_contents_atomic("/var/run/nchan.pid",implode("\n",$nchan)."\n"); + } else { + @unlink("/var/run/nchan.pid"); + } +} ?> From fc43ec7bfe786b2459a217ca61119dc455099ade Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sat, 9 Aug 2025 22:20:42 -0400 Subject: [PATCH 03/15] Update publish.php --- emhttp/plugins/dynamix/include/publish.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emhttp/plugins/dynamix/include/publish.php b/emhttp/plugins/dynamix/include/publish.php index 34e085f74..664e960f4 100644 --- a/emhttp/plugins/dynamix/include/publish.php +++ b/emhttp/plugins/dynamix/include/publish.php @@ -29,8 +29,8 @@ function curl_socket($socket, $url, $message='') { // If a script publishes to multiple endpoints, timing out on one endpoint will terminate the entire script even if other enpoints succeed. // If this is a problem, don't use $abort and instead handle this in the script or utilize a single sript per endpoint. function publish($endpoint, $message, $len=1, $abort=false, $abortTime = 120) { - static $abortStart, $com, $lens = []; - + static $abortStart = [], $com = [], $lens = []; + if ( is_file("/tmp/publishPaused") ) return false; From ac359b4094a803104fff0a6c7707379b3811fded Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sat, 9 Aug 2025 22:39:28 -0400 Subject: [PATCH 04/15] Feat: Allow update 1,2,3 on dashboard to exit --- emhttp/plugins/dynamix/nchan/update_1 | 2 +- emhttp/plugins/dynamix/nchan/update_2 | 2 +- emhttp/plugins/dynamix/nchan/update_3 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/emhttp/plugins/dynamix/nchan/update_1 b/emhttp/plugins/dynamix/nchan/update_1 index 1f13f6b52..b34b8b83f 100755 --- a/emhttp/plugins/dynamix/nchan/update_1 +++ b/emhttp/plugins/dynamix/nchan/update_1 @@ -125,7 +125,7 @@ while (true) { $echo = json_encode($echo); $md5_new = md5($echo,true); if ($md5_new !== $md5_old) { - $md5_old = publish('update1',$echo)!==false ? $md5_new : -1; + $md5_old = publish('update1',$echo,1,true)!==false ? $md5_new : -1; } sleep(5); } diff --git a/emhttp/plugins/dynamix/nchan/update_2 b/emhttp/plugins/dynamix/nchan/update_2 index d8f682750..197a7fd7a 100755 --- a/emhttp/plugins/dynamix/nchan/update_2 +++ b/emhttp/plugins/dynamix/nchan/update_2 @@ -502,7 +502,7 @@ while (true) { $echo = json_encode($echo); $md5_new = md5($echo,true); if ($md5_new !== $md5_old) { - $md5_old = publish('update2',$echo)!==false ? $md5_new : -1; + $md5_old = publish('update2',$echo,1,true)!==false ? $md5_new : -1; } sleep(2); } diff --git a/emhttp/plugins/dynamix/nchan/update_3 b/emhttp/plugins/dynamix/nchan/update_3 index 9dd703774..e0aa82cf9 100755 --- a/emhttp/plugins/dynamix/nchan/update_3 +++ b/emhttp/plugins/dynamix/nchan/update_3 @@ -162,7 +162,7 @@ while (true) { $echo = json_encode($echo); $md5_new = md5($echo,true); if ($md5_new !== $md5_old) { - $md5_old = publish('update3',$echo)!==false ? $md5_new : -1; + $md5_old = publish('update3',$echo,1,true)!==false ? $md5_new : -1; $time0 = $time1; } sleep(1); From 1e19f598593831cad78434c3f0509278c055782d Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sat, 9 Aug 2025 22:50:16 -0400 Subject: [PATCH 05/15] Update docker_load --- .../plugins/dynamix.docker.manager/nchan/docker_load | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load index 11271704f..ed8b7e52a 100755 --- a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load +++ b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load @@ -18,12 +18,13 @@ require_once "$docroot/webGui/include/Helpers.php"; require_once "$docroot/webGui/include/publish.php"; while (true) { - $output = shell_exec("docker stats --no-stream --format='{{.ID}};{{.CPUPerc}};{{.MemUsage}}'"); - if ($output === false) { - my_logger("docker stats error: $output"); + $output = shell_exec("docker stats --no-stream --format='{{.ID}};{{.CPUPerc}};{{.MemUsage}}' 2>&1"); + if ($output === null) { + my_logger("docker stats failed"); + removeNChanScript(); exit(1); } // publish and exit the script if no listeners after 120 seconds - publish("dockerload", $output, 1, true, 120); + publish("dockerload", $output, 1, true); sleep(1); -} +} \ No newline at end of file From e57011bc3866699a814539f82b03946208fc4e8a Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sun, 10 Aug 2025 12:47:10 -0400 Subject: [PATCH 06/15] Simpler Syntax for calling publish function --- .../dynamix.docker.manager/nchan/docker_load | 2 +- .../plugins/dynamix.vm.manager/nchan/vm_usage | 2 +- emhttp/plugins/dynamix/include/publish.php | 17 ++++++++++++++++- emhttp/plugins/dynamix/nchan/update_1 | 2 +- emhttp/plugins/dynamix/nchan/update_2 | 2 +- emhttp/plugins/dynamix/nchan/update_3 | 2 +- emhttp/plugins/dynamix/nchan/ups_status | 2 +- emhttp/plugins/dynamix/nchan/wg_poller | 2 +- emhttp/plugins/dynamix/nchan/wlan0 | 3 ++- 9 files changed, 25 insertions(+), 9 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load index ed8b7e52a..59f4c8b42 100755 --- a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load +++ b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load @@ -25,6 +25,6 @@ while (true) { exit(1); } // publish and exit the script if no listeners after 120 seconds - publish("dockerload", $output, 1, true); + publish("dockerload", $output,true); sleep(1); } \ No newline at end of file diff --git a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage index 194e3f4e4..751a0445a 100755 --- a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage +++ b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage @@ -90,7 +90,7 @@ while (true) { $echo = json_encode($echo); $md5_new = md5($echo,true); if ($md5_new !== $md5_old) { - $md5_old = publish('vm_usage',$echo)!==false ? $md5_new : -1; + $md5_old = publish('vm_usage',$echo,true)!==false ? $md5_new : -1; } sleep($timer); diff --git a/emhttp/plugins/dynamix/include/publish.php b/emhttp/plugins/dynamix/include/publish.php index 664e960f4..390b784c4 100644 --- a/emhttp/plugins/dynamix/include/publish.php +++ b/emhttp/plugins/dynamix/include/publish.php @@ -28,12 +28,27 @@ function curl_socket($socket, $url, $message='') { // $abort: if true, the script will exit if the endpoint is without subscribers on the next publish attempt after $abortTime seconds // If a script publishes to multiple endpoints, timing out on one endpoint will terminate the entire script even if other enpoints succeed. // If this is a problem, don't use $abort and instead handle this in the script or utilize a single sript per endpoint. -function publish($endpoint, $message, $len=1, $abort=false, $abortTime = 120) { +// +// $opt1: length of the buffer. If not numeric, it's a boolean for $abort. If not numeric, it's a boolean for $abort. +// $opt2: if $opt1 is not numeric, it's a boolean for $abort. +// $opt3: if $opt1 is not numeric, it's a value for $abortTime. +function publish($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { static $abortStart = [], $com = [], $lens = []; if ( is_file("/tmp/publishPaused") ) return false; + // handle the $opt1/$opt2/$opt3 parameters while remaining backwards compatible + if ( is_numeric($opt1) ) { + $len = $opt1; + $abort = $opt2; + $abortTime = $opt3; + } else { + $len = 1; + $abort = $opt1; + $abortTime = $opt2 ?: $opt3; + } + // Check for the unlikely case of a buffer length change if ( (($lens[$endpoint] ?? 1) !== $len) && isset($com[$endpoint]) ) { curl_close($com[$endpoint]); diff --git a/emhttp/plugins/dynamix/nchan/update_1 b/emhttp/plugins/dynamix/nchan/update_1 index b34b8b83f..143846994 100755 --- a/emhttp/plugins/dynamix/nchan/update_1 +++ b/emhttp/plugins/dynamix/nchan/update_1 @@ -125,7 +125,7 @@ while (true) { $echo = json_encode($echo); $md5_new = md5($echo,true); if ($md5_new !== $md5_old) { - $md5_old = publish('update1',$echo,1,true)!==false ? $md5_new : -1; + $md5_old = publish('update1',$echo,true)!==false ? $md5_new : -1; } sleep(5); } diff --git a/emhttp/plugins/dynamix/nchan/update_2 b/emhttp/plugins/dynamix/nchan/update_2 index 197a7fd7a..bf68b72c2 100755 --- a/emhttp/plugins/dynamix/nchan/update_2 +++ b/emhttp/plugins/dynamix/nchan/update_2 @@ -502,7 +502,7 @@ while (true) { $echo = json_encode($echo); $md5_new = md5($echo,true); if ($md5_new !== $md5_old) { - $md5_old = publish('update2',$echo,1,true)!==false ? $md5_new : -1; + $md5_old = publish('update2',$echo,true)!==false ? $md5_new : -1; } sleep(2); } diff --git a/emhttp/plugins/dynamix/nchan/update_3 b/emhttp/plugins/dynamix/nchan/update_3 index e0aa82cf9..5d670cf75 100755 --- a/emhttp/plugins/dynamix/nchan/update_3 +++ b/emhttp/plugins/dynamix/nchan/update_3 @@ -162,7 +162,7 @@ while (true) { $echo = json_encode($echo); $md5_new = md5($echo,true); if ($md5_new !== $md5_old) { - $md5_old = publish('update3',$echo,1,true)!==false ? $md5_new : -1; + $md5_old = publish('update3',$echo,true)!==false ? $md5_new : -1; $time0 = $time1; } sleep(1); diff --git a/emhttp/plugins/dynamix/nchan/ups_status b/emhttp/plugins/dynamix/nchan/ups_status index 05d203a0b..ca25805e0 100755 --- a/emhttp/plugins/dynamix/nchan/ups_status +++ b/emhttp/plugins/dynamix/nchan/ups_status @@ -134,7 +134,7 @@ while (true) { $echo = json_encode($echo); $md5_new = md5($echo,true); if ($md5_new !== $md5_old) { - $md5_old = publish('apcups',$echo)!==false ? $md5_new : -1; + $md5_old = publish('apcups',$echo,true)!==false ? $md5_new : -1; } sleep(3); } diff --git a/emhttp/plugins/dynamix/nchan/wg_poller b/emhttp/plugins/dynamix/nchan/wg_poller index 3645f40e9..875519448 100755 --- a/emhttp/plugins/dynamix/nchan/wg_poller +++ b/emhttp/plugins/dynamix/nchan/wg_poller @@ -40,7 +40,7 @@ while (true) { $echo = json_encode($echo); $md5_new = md5($echo,true); if ($md5_new !== $md5_old) { - $md5_old = publish('wireguard',$echo)!==false ? $md5_new : -1; + $md5_old = publish('wireguard',$echo,true)!==false ? $md5_new : -1; } sleep(1); } diff --git a/emhttp/plugins/dynamix/nchan/wlan0 b/emhttp/plugins/dynamix/nchan/wlan0 index 57a9ed993..34e2b5c6e 100755 --- a/emhttp/plugins/dynamix/nchan/wlan0 +++ b/emhttp/plugins/dynamix/nchan/wlan0 @@ -65,7 +65,8 @@ while (true) { $echo['title'] = _('WiFi status unavailable'); } } - publish('wlan0',json_encode($echo)); + // Short of closing all web pages, the timeout should only happen if wifi is enabled and then disabled + publish('wlan0',json_encode($echo),1,true); sleep(3); } ?> From 353ae247b83f3950d83f20ef74209823a84b9072 Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sun, 10 Aug 2025 16:29:29 -0400 Subject: [PATCH 07/15] Fixed: dockerload exiting if no containers running --- .../dynamix.docker.manager/nchan/docker_load | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load index 59f4c8b42..b28084bb9 100755 --- a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load +++ b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load @@ -17,14 +17,34 @@ $docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'); require_once "$docroot/webGui/include/Helpers.php"; require_once "$docroot/webGui/include/publish.php"; +$noDockerStats = false; +$noDockerStatsTime = null; +$exitAfterTimeout = 120; + while (true) { $output = shell_exec("docker stats --no-stream --format='{{.ID}};{{.CPUPerc}};{{.MemUsage}}' 2>&1"); - if ($output === null) { - my_logger("docker stats failed"); - removeNChanScript(); - exit(1); + + if ( ! $noDockerStats ) { + // publish and exit the script if no listeners after the timeout + publish("dockerload", $output,true,$exitAfterTimeout); + } + if ( $output === null ) { + // Don't continually publish messages if no stats are available -> only publish the first time + $noDockerStats = true; + + if ( ! $noDockerStatsTime ) { + $noDockerStatsTime = time(); + } + + // handle if no containers are running and user navigates to another page. + // publish requires a second publish attempt with no listeners in order to exit the script after the timeout has elapsed + if ( (time() - $noDockerStatsTime) > $exitAfterTimeout ) { + $noDockerStats = false; + $noDockerStatsTime = null; + } + sleep(10); + } else { + $noDockerStats = false; + sleep(1); } - // publish and exit the script if no listeners after 120 seconds - publish("dockerload", $output,true); - sleep(1); } \ No newline at end of file From fa5c87cc7555f8dffc6fb339795fcae4493ba635 Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sun, 10 Aug 2025 16:44:06 -0400 Subject: [PATCH 08/15] Refactor docker_load keep publishing at a slower rate if no containers are running. Precursor to having publish not publish if md5 hasn't changed but still honoring timeouts. --- .../dynamix.docker.manager/nchan/docker_load | 24 ++----------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load index b28084bb9..6cc8be993 100755 --- a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load +++ b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load @@ -17,34 +17,14 @@ $docroot ??= ($_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'); require_once "$docroot/webGui/include/Helpers.php"; require_once "$docroot/webGui/include/publish.php"; -$noDockerStats = false; -$noDockerStatsTime = null; -$exitAfterTimeout = 120; - while (true) { $output = shell_exec("docker stats --no-stream --format='{{.ID}};{{.CPUPerc}};{{.MemUsage}}' 2>&1"); - if ( ! $noDockerStats ) { - // publish and exit the script if no listeners after the timeout - publish("dockerload", $output,true,$exitAfterTimeout); - } + publish("dockerload", $output,true); if ( $output === null ) { - // Don't continually publish messages if no stats are available -> only publish the first time - $noDockerStats = true; - - if ( ! $noDockerStatsTime ) { - $noDockerStatsTime = time(); - } - - // handle if no containers are running and user navigates to another page. - // publish requires a second publish attempt with no listeners in order to exit the script after the timeout has elapsed - if ( (time() - $noDockerStatsTime) > $exitAfterTimeout ) { - $noDockerStats = false; - $noDockerStatsTime = null; - } + // slow down publishing if no containers are running sleep(10); } else { - $noDockerStats = false; sleep(1); } } \ No newline at end of file From 408331edf500f2dd7d2a39a52fdfe3d1bdf1eaad Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sun, 10 Aug 2025 18:13:10 -0400 Subject: [PATCH 09/15] Refactor: Support not sending duplicate messages Keep track of the md5 within a separate function. Avoids duplication of code on the nchan scripts, and allows for the script to still exit if no listeners without adding in more code within each script to handle this. --- .../dynamix.docker.manager/nchan/docker_load | 2 +- .../plugins/dynamix.vm.manager/nchan/vm_usage | 5 +-- emhttp/plugins/dynamix/include/publish.php | 32 ++++++++++++++++++- emhttp/plugins/dynamix/nchan/update_1 | 6 ++-- emhttp/plugins/dynamix/nchan/update_2 | 5 +-- emhttp/plugins/dynamix/nchan/update_3 | 7 ++-- emhttp/plugins/dynamix/nchan/ups_status | 7 ++-- emhttp/plugins/dynamix/nchan/wg_poller | 5 +-- emhttp/plugins/dynamix/nchan/wlan0 | 2 +- 9 files changed, 43 insertions(+), 28 deletions(-) diff --git a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load index 6cc8be993..e9ebe1984 100755 --- a/emhttp/plugins/dynamix.docker.manager/nchan/docker_load +++ b/emhttp/plugins/dynamix.docker.manager/nchan/docker_load @@ -20,7 +20,7 @@ require_once "$docroot/webGui/include/publish.php"; while (true) { $output = shell_exec("docker stats --no-stream --format='{{.ID}};{{.CPUPerc}};{{.MemUsage}}' 2>&1"); - publish("dockerload", $output,true); + publish_md5("dockerload", $output,true); if ( $output === null ) { // slow down publishing if no containers are running sleep(10); diff --git a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage index 751a0445a..6af185358 100755 --- a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage +++ b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage @@ -88,10 +88,7 @@ while (true) { if ($running < 1) $echo = ""._('No VMs running').""; $echo = json_encode($echo); - $md5_new = md5($echo,true); - if ($md5_new !== $md5_old) { - $md5_old = publish('vm_usage',$echo,true)!==false ? $md5_new : -1; - } + publish_md5('vm_usage',$echo,true); sleep($timer); } diff --git a/emhttp/plugins/dynamix/include/publish.php b/emhttp/plugins/dynamix/include/publish.php index 390b784c4..a8dfd52f1 100644 --- a/emhttp/plugins/dynamix/include/publish.php +++ b/emhttp/plugins/dynamix/include/publish.php @@ -34,7 +34,7 @@ function curl_socket($socket, $url, $message='') { // $opt3: if $opt1 is not numeric, it's a value for $abortTime. function publish($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { static $abortStart = [], $com = [], $lens = []; - + if ( is_file("/tmp/publishPaused") ) return false; @@ -107,6 +107,36 @@ function publish($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { return $reply; } +// Function to not continually republish the same message if it hasn't changed since the last publish +function publish_md5($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { + static $md5_old = []; + static $md5_time = []; + + if ( is_numeric($opt1) ) { + $timeout = $opt3; + $abort = $opt2; + } else { + $abort = $opt1; + $timeout = $opt2 ?: $opt3; + } + + // if abort is set, republish the message even if it hasn't changed after $timeout seconds to check for subscribers and exit accordingly + if ( $abort ) { + if ( (time() - ($md5_time[$endpoint]??0)) > $timeout ) { + $md5_old[$endpoint] = null; + } + } + + $md5_new = $message ? md5($message,true) : -1 ; + if ($md5_new !== ($md5_old[$endpoint]??null)) { + $md5_old[$endpoint] = $md5_new; + $md5_time[$endpoint] = time(); + + return publish($endpoint, $message, $opt1, $opt2, $opt3); + } +} + + // Removes the script calling this function from nchan.pid function removeNChanScript() { global $docroot, $argv; diff --git a/emhttp/plugins/dynamix/nchan/update_1 b/emhttp/plugins/dynamix/nchan/update_1 index 143846994..f43f425b5 100755 --- a/emhttp/plugins/dynamix/nchan/update_1 +++ b/emhttp/plugins/dynamix/nchan/update_1 @@ -123,10 +123,8 @@ while (true) { $count = array_count_values($lsof ?? array()); foreach ($share as $name) $echo['stream'][] = $count[$name]??0; $echo = json_encode($echo); - $md5_new = md5($echo,true); - if ($md5_new !== $md5_old) { - $md5_old = publish('update1',$echo,true)!==false ? $md5_new : -1; - } + publish_md5('update1',$echo,true); + sleep(5); } ?> diff --git a/emhttp/plugins/dynamix/nchan/update_2 b/emhttp/plugins/dynamix/nchan/update_2 index bf68b72c2..9706262d1 100755 --- a/emhttp/plugins/dynamix/nchan/update_2 +++ b/emhttp/plugins/dynamix/nchan/update_2 @@ -500,10 +500,7 @@ while (true) { } $echo = json_encode($echo); - $md5_new = md5($echo,true); - if ($md5_new !== $md5_old) { - $md5_old = publish('update2',$echo,true)!==false ? $md5_new : -1; - } + publish_md5('update2',$echo,true); sleep(2); } ?> diff --git a/emhttp/plugins/dynamix/nchan/update_3 b/emhttp/plugins/dynamix/nchan/update_3 index 5d670cf75..d81b9bd34 100755 --- a/emhttp/plugins/dynamix/nchan/update_3 +++ b/emhttp/plugins/dynamix/nchan/update_3 @@ -160,11 +160,8 @@ while (true) { $echo['time'] = [$clock,_($date,0)]; $echo = json_encode($echo); - $md5_new = md5($echo,true); - if ($md5_new !== $md5_old) { - $md5_old = publish('update3',$echo,true)!==false ? $md5_new : -1; - $time0 = $time1; - } + publish_md5('update3',$echo,true); + sleep(1); $time1 = microtime(true); } diff --git a/emhttp/plugins/dynamix/nchan/ups_status b/emhttp/plugins/dynamix/nchan/ups_status index ca25805e0..b201d424c 100755 --- a/emhttp/plugins/dynamix/nchan/ups_status +++ b/emhttp/plugins/dynamix/nchan/ups_status @@ -132,10 +132,9 @@ while (true) { $echo[6] = isset($output) ? ((empty($volt) || ($minv<$output && $output<$maxv) ? "" : "").$echo[6].(isset($freq) ? " ~ $freq Hz" : "")."") : $echo[6]; } $echo = json_encode($echo); - $md5_new = md5($echo,true); - if ($md5_new !== $md5_old) { - $md5_old = publish('apcups',$echo,true)!==false ? $md5_new : -1; - } + + publish_md5('apcups',$echo,true); + sleep(3); } ?> diff --git a/emhttp/plugins/dynamix/nchan/wg_poller b/emhttp/plugins/dynamix/nchan/wg_poller index 875519448..786e8f00a 100755 --- a/emhttp/plugins/dynamix/nchan/wg_poller +++ b/emhttp/plugins/dynamix/nchan/wg_poller @@ -38,10 +38,7 @@ while (true) { if (count($row)>5) $echo[] = [$row[0], $row[5]?$now-$row[5]:0, my_scale($row[6],$unit)." $unit", my_scale($row[7],$unit)." $unit"]; } $echo = json_encode($echo); - $md5_new = md5($echo,true); - if ($md5_new !== $md5_old) { - $md5_old = publish('wireguard',$echo,true)!==false ? $md5_new : -1; - } + publish_md5('wireguard',$echo,true); sleep(1); } ?> diff --git a/emhttp/plugins/dynamix/nchan/wlan0 b/emhttp/plugins/dynamix/nchan/wlan0 index 34e2b5c6e..dba908aa1 100755 --- a/emhttp/plugins/dynamix/nchan/wlan0 +++ b/emhttp/plugins/dynamix/nchan/wlan0 @@ -66,7 +66,7 @@ while (true) { } } // Short of closing all web pages, the timeout should only happen if wifi is enabled and then disabled - publish('wlan0',json_encode($echo),1,true); + publish_md5('wlan0',json_encode($echo),true); sleep(3); } ?> From 879e1cba41202983547204e09f852da3aacb09db Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sun, 10 Aug 2025 18:22:21 -0400 Subject: [PATCH 10/15] Feat support string or array passed as a message --- emhttp/plugins/dynamix.vm.manager/nchan/vm_usage | 1 - emhttp/plugins/dynamix/include/publish.php | 9 +++++++++ emhttp/plugins/dynamix/nchan/update_1 | 2 +- emhttp/plugins/dynamix/nchan/update_2 | 1 - emhttp/plugins/dynamix/nchan/update_3 | 1 - emhttp/plugins/dynamix/nchan/ups_status | 1 - emhttp/plugins/dynamix/nchan/wg_poller | 1 - emhttp/plugins/dynamix/nchan/wlan0 | 2 +- 8 files changed, 11 insertions(+), 7 deletions(-) diff --git a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage index 6af185358..b51c22cd1 100755 --- a/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage +++ b/emhttp/plugins/dynamix.vm.manager/nchan/vm_usage @@ -87,7 +87,6 @@ while (true) { } if ($running < 1) $echo = ""._('No VMs running').""; - $echo = json_encode($echo); publish_md5('vm_usage',$echo,true); sleep($timer); diff --git a/emhttp/plugins/dynamix/include/publish.php b/emhttp/plugins/dynamix/include/publish.php index a8dfd52f1..e7b5708f1 100644 --- a/emhttp/plugins/dynamix/include/publish.php +++ b/emhttp/plugins/dynamix/include/publish.php @@ -25,6 +25,7 @@ function curl_socket($socket, $url, $message='') { return $reply; } +// $message: if an array, it will be converted to a JSON string // $abort: if true, the script will exit if the endpoint is without subscribers on the next publish attempt after $abortTime seconds // If a script publishes to multiple endpoints, timing out on one endpoint will terminate the entire script even if other enpoints succeed. // If this is a problem, don't use $abort and instead handle this in the script or utilize a single sript per endpoint. @@ -38,6 +39,10 @@ function publish($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { if ( is_file("/tmp/publishPaused") ) return false; + if ( is_array($message) ) { + $message = json_encode($message,true); + } + // handle the $opt1/$opt2/$opt3 parameters while remaining backwards compatible if ( is_numeric($opt1) ) { $len = $opt1; @@ -120,6 +125,10 @@ function publish_md5($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { $timeout = $opt2 ?: $opt3; } + if ( is_array($message) ) { + $message = json_encode($message,true); + } + // if abort is set, republish the message even if it hasn't changed after $timeout seconds to check for subscribers and exit accordingly if ( $abort ) { if ( (time() - ($md5_time[$endpoint]??0)) > $timeout ) { diff --git a/emhttp/plugins/dynamix/nchan/update_1 b/emhttp/plugins/dynamix/nchan/update_1 index f43f425b5..1c33a4a16 100755 --- a/emhttp/plugins/dynamix/nchan/update_1 +++ b/emhttp/plugins/dynamix/nchan/update_1 @@ -122,7 +122,7 @@ while (true) { $share = array_keys($shares); $count = array_count_values($lsof ?? array()); foreach ($share as $name) $echo['stream'][] = $count[$name]??0; - $echo = json_encode($echo); + publish_md5('update1',$echo,true); sleep(5); diff --git a/emhttp/plugins/dynamix/nchan/update_2 b/emhttp/plugins/dynamix/nchan/update_2 index 9706262d1..460cd6661 100755 --- a/emhttp/plugins/dynamix/nchan/update_2 +++ b/emhttp/plugins/dynamix/nchan/update_2 @@ -499,7 +499,6 @@ while (true) { $echo[$a] = [implode($echo[$a]), $extra]; } - $echo = json_encode($echo); publish_md5('update2',$echo,true); sleep(2); } diff --git a/emhttp/plugins/dynamix/nchan/update_3 b/emhttp/plugins/dynamix/nchan/update_3 index d81b9bd34..a17ce1a9c 100755 --- a/emhttp/plugins/dynamix/nchan/update_3 +++ b/emhttp/plugins/dynamix/nchan/update_3 @@ -159,7 +159,6 @@ while (true) { $date = my_date($xdate ? 'D j M Y, T' : $display['date'].', T',$now); $echo['time'] = [$clock,_($date,0)]; - $echo = json_encode($echo); publish_md5('update3',$echo,true); sleep(1); diff --git a/emhttp/plugins/dynamix/nchan/ups_status b/emhttp/plugins/dynamix/nchan/ups_status index b201d424c..e3c7f71eb 100755 --- a/emhttp/plugins/dynamix/nchan/ups_status +++ b/emhttp/plugins/dynamix/nchan/ups_status @@ -131,7 +131,6 @@ while (true) { elseif (isset($load)) $echo[5] = ($load<90 ? "" : "").$echo[5].""; $echo[6] = isset($output) ? ((empty($volt) || ($minv<$output && $output<$maxv) ? "" : "").$echo[6].(isset($freq) ? " ~ $freq Hz" : "")."") : $echo[6]; } - $echo = json_encode($echo); publish_md5('apcups',$echo,true); diff --git a/emhttp/plugins/dynamix/nchan/wg_poller b/emhttp/plugins/dynamix/nchan/wg_poller index 786e8f00a..6cb205711 100755 --- a/emhttp/plugins/dynamix/nchan/wg_poller +++ b/emhttp/plugins/dynamix/nchan/wg_poller @@ -37,7 +37,6 @@ while (true) { $row = preg_split('/\s+/',$row); if (count($row)>5) $echo[] = [$row[0], $row[5]?$now-$row[5]:0, my_scale($row[6],$unit)." $unit", my_scale($row[7],$unit)." $unit"]; } - $echo = json_encode($echo); publish_md5('wireguard',$echo,true); sleep(1); } diff --git a/emhttp/plugins/dynamix/nchan/wlan0 b/emhttp/plugins/dynamix/nchan/wlan0 index dba908aa1..c05b23eea 100755 --- a/emhttp/plugins/dynamix/nchan/wlan0 +++ b/emhttp/plugins/dynamix/nchan/wlan0 @@ -66,7 +66,7 @@ while (true) { } } // Short of closing all web pages, the timeout should only happen if wifi is enabled and then disabled - publish_md5('wlan0',json_encode($echo),true); + publish_md5('wlan0',$echo,true); sleep(3); } ?> From 32d04532f3071803b9381238584cb9ef1979db6f Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sun, 10 Aug 2025 19:25:49 -0400 Subject: [PATCH 11/15] fix typo --- emhttp/plugins/dynamix/include/publish.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/emhttp/plugins/dynamix/include/publish.php b/emhttp/plugins/dynamix/include/publish.php index e7b5708f1..ce3887f17 100644 --- a/emhttp/plugins/dynamix/include/publish.php +++ b/emhttp/plugins/dynamix/include/publish.php @@ -40,7 +40,7 @@ function publish($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { return false; if ( is_array($message) ) { - $message = json_encode($message,true); + $message = json_encode($message); } // handle the $opt1/$opt2/$opt3 parameters while remaining backwards compatible @@ -126,7 +126,7 @@ function publish_md5($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { } if ( is_array($message) ) { - $message = json_encode($message,true); + $message = json_encode($message); } // if abort is set, republish the message even if it hasn't changed after $timeout seconds to check for subscribers and exit accordingly @@ -150,12 +150,11 @@ function publish_md5($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { function removeNChanScript() { global $docroot, $argv; - $script = str_replace("$docroot/","",(php_sapi_name() === 'cli') ? $argv[0] : $_SERVER['argv'][0]); + $script = trim(str_replace("$docroot/","",(php_sapi_name() === 'cli') ? $argv[0] : $_SERVER['argv'][0])); $nchan = @file("/var/run/nchan.pid",FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: []; $nchan = array_filter($nchan,function($x) use ($script) { return $script !== trim(explode(":",$x)[0]); }); - if (count($nchan) > 0) { file_put_contents_atomic("/var/run/nchan.pid",implode("\n",$nchan)."\n"); } else { From a981e63a622980a64d86ce8ee14669f1ec04c63d Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sun, 10 Aug 2025 19:31:43 -0400 Subject: [PATCH 12/15] Refactor: vmdashusage updates nchan.pid consistent with publish.php --- emhttp/plugins/dynamix/nchan/vm_dashusage | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/emhttp/plugins/dynamix/nchan/vm_dashusage b/emhttp/plugins/dynamix/nchan/vm_dashusage index 90979e36e..e8d5de2bd 100755 --- a/emhttp/plugins/dynamix/nchan/vm_dashusage +++ b/emhttp/plugins/dynamix/nchan/vm_dashusage @@ -40,14 +40,14 @@ if ($var['fsState'] == "Started" || $var['fsState'] == "Starting") { } sleep(10); } elseif ($domain_cfg['SERVICE'] != "enable") { - #Add remove_nchan_pid_entry("webGui/nchan/vm_dashusage"); - exec("sed -i '/webGui\/nchan\/vm_dashusage/d' /var/run/nchan.pid"); - return; + sleep(10); + removeNChanScript(); + exit; } } else { - #Add remove_nchan_pid_entry("webGui/nchan/vm_dashusage"); - exec("sed -i '/webGui\/nchan\/vm_dashusage/d' /var/run/nchan.pid"); - return; + sleep(10); + removeNChanScript(); + exit; } require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php"; @@ -109,11 +109,8 @@ while (true) { } } - $echo = json_encode($echo); - $md5_new = md5($echo,true); - if ($md5_new !== $md5_old) { - $md5_old = publish('vm_dashusage',$echo)!==false ? $md5_new : -1; - } + publish_md5('vm_dashusage',$echo,true); + sleep($timer); } ?> From fb98b20982007ee95b926e7239578d98c7221bb0 Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sun, 10 Aug 2025 19:49:01 -0400 Subject: [PATCH 13/15] Update emhttp/plugins/dynamix/include/publish.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- emhttp/plugins/dynamix/include/publish.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/include/publish.php b/emhttp/plugins/dynamix/include/publish.php index ce3887f17..0a50d0acd 100644 --- a/emhttp/plugins/dynamix/include/publish.php +++ b/emhttp/plugins/dynamix/include/publish.php @@ -11,7 +11,7 @@ */ ?> Date: Sun, 10 Aug 2025 22:37:30 -0400 Subject: [PATCH 14/15] Update emhttp/plugins/dynamix/include/publish.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- emhttp/plugins/dynamix/include/publish.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emhttp/plugins/dynamix/include/publish.php b/emhttp/plugins/dynamix/include/publish.php index 0a50d0acd..79a5e24cb 100644 --- a/emhttp/plugins/dynamix/include/publish.php +++ b/emhttp/plugins/dynamix/include/publish.php @@ -136,7 +136,8 @@ function publish_md5($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { } } - $md5_new = $message ? md5($message,true) : -1 ; + // Always hash the payload to avoid collapsing distinct "falsey" values + $md5_new = md5((string)$message, true); if ($md5_new !== ($md5_old[$endpoint]??null)) { $md5_old[$endpoint] = $md5_new; $md5_time[$endpoint] = time(); From b15416219ff7defc154ed7aef1091c08b7401f43 Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Mon, 11 Aug 2025 13:14:33 -0400 Subject: [PATCH 15/15] Update comments --- emhttp/plugins/dynamix/include/publish.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/emhttp/plugins/dynamix/include/publish.php b/emhttp/plugins/dynamix/include/publish.php index 79a5e24cb..beb75ee21 100644 --- a/emhttp/plugins/dynamix/include/publish.php +++ b/emhttp/plugins/dynamix/include/publish.php @@ -30,9 +30,9 @@ function curl_socket($socket, $url, $message='') { // If a script publishes to multiple endpoints, timing out on one endpoint will terminate the entire script even if other enpoints succeed. // If this is a problem, don't use $abort and instead handle this in the script or utilize a single sript per endpoint. // -// $opt1: length of the buffer. If not numeric, it's a boolean for $abort. If not numeric, it's a boolean for $abort. -// $opt2: if $opt1 is not numeric, it's a boolean for $abort. -// $opt3: if $opt1 is not numeric, it's a value for $abortTime. +// $opt1: if numeric it's the length of the buffer. If its true|false it signifies whether to utilise the abort if no listeners. +// $opt2: if $opt1 is numeric, it's a boolean for $abort. If $opt1 is boolean, its the timeout defaulting to $opt3 +// $opt3: if $opt1 is numeric, it's a value for $abortTime. If $opt1 is boolean, this parameter shouldn't be used function publish($endpoint, $message, $opt1=1, $opt2=false, $opt3=120) { static $abortStart = [], $com = [], $lens = [];