Skip to content

Commit

Permalink
Fix stats shared variable handling and drop dependencies
Browse files Browse the repository at this point in the history
Simplify code and add more comments
  • Loading branch information
iliajie committed Jun 26, 2024
1 parent cbc039a commit 5fb8be0
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 43 deletions.
8 changes: 4 additions & 4 deletions stats-lib.pl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ sub jsonify

sub stats
{
my ($stack) = @_;
my ($history) = @_;
my %data;
my $tdata = {};
my $fdatad = "$var_directory/modules/$current_theme";
Expand Down Expand Up @@ -86,10 +86,10 @@ sub stats
unlock_file($fdata);

# Return requested data
if ($stack) {
$data{'fcached'} = $cdata;
if ($history) {
$data{'_history'} = $cdata;
} else {
$data{'scached'} = $tdata;
$data{'_current'} = $tdata;
}
}
return;
Expand Down
3 changes: 1 addition & 2 deletions stats.cgi
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ if (!defined(&webmin_user_is_admin) || !webmin_user_is_admin()) {
# Check dependencies
my @errors;
my @modnames = ("Digest::SHA", "Digest::MD5", "IO::Select",
"Time::HiRes", "Net::WebSocket::Server",
"threads", "threads::shared");
"Time::HiRes", "Net::WebSocket::Server");

foreach my $modname (@modnames) {
eval "use ${modname};";
Expand Down
71 changes: 34 additions & 37 deletions stats.pl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use Net::WebSocket::Server;
use utf8;
use JSON;
use threads::shared;

our ($current_theme);
require($ENV{'THEME_ROOT'} . "/stats-lib.pl");
Expand All @@ -36,45 +35,40 @@
# Log successful connection
error_stderr("WebSocket server is listening on port $port");

# Used variables
my $stats_stack :shared = 0;
my $stats_interval :shared = 1;
my $stats_running :shared = 1;
my $clients_connected :shared = 0;
my $server_shutdown :shared = 0;
my $server_paused :shared = 0;

# Start WebSocket server
Net::WebSocket::Server->new(
listen => $port,
tick_period => 1,
on_tick => sub {
my ($serv) = @_;
# Has any connection requested full set of stats
my $history = grep {
$serv->{'conns'}->{$_}->{'conn'}->{'history'} }
keys %{$serv->{'conns'}};
# If asked to stop running, then shut down the server
if (!$stats_running) {
if ($serv->{'disable'}) {
$serv->shutdown();
return;
}
# Collect stats and send them to all connected clients unless paused
my $stats = encode_json(stats($stats_stack));
if (!$server_paused) {
foreach my $conn_id (keys %{$serv->{'conns'}}) {
my $conn = $serv->{'conns'}->{$conn_id}->{'conn'};
if ($conn->{'verified'}) {
$conn->send_utf8($stats);
}
my $stats = encode_json(stats($history));
foreach my $conn_id (keys %{$serv->{'conns'}}) {
my $conn = $serv->{'conns'}->{$conn_id}->{'conn'};
if ($conn->{'verified'}) {
$conn->{'history'} = 0;
!$conn->{'paused'} && $conn->send_utf8($stats);
}
}
# If interval is set then sleep minus one
# second becase tick_period is one second
if ($stats_interval > 1) {
sleep($stats_interval-1);
if ($serv->{'interval'} > 1) {
sleep($serv->{'interval'}-1);
}
},
on_connect => sub {
my ($serv, $conn) = @_;
error_stderr("WebSocket connection $conn->{'port'} established");
$clients_connected++;
$serv->{'clients_connected'}++;
alarm(0);
# Set post-connect activity timeout
$SIG{'ALRM'} = sub {
Expand Down Expand Up @@ -105,34 +99,37 @@
return;
}
}
# Update shared variables
$stats_stack = $data->{'stack'} // 0;
$stats_interval = $data->{'interval'} // 1;
$stats_running = $data->{'running'} // 1;
$server_shutdown = $data->{'shutdown'} // 0;
$server_paused = $data->{'paused'} // 0;
# Update connection variables
$conn->{'paused'} = $data->{'paused'} // 0;
$conn->{'history'} = $data->{'history'} // 0;
# Update WebSocket server variables
$serv->{'interval'} = $data->{'interval'} // 1;
$serv->{'disable'} = $data->{'disable'} // 0;
$serv->{'shutdown'} = $data->{'shutdown'} // 0;
},
disconnect => sub {
my ($conn) = @_;
$clients_connected--;
$serv->{'clients_connected'}--;
error_stderr("WebSocket connection $conn->{'port'} closed");
# If shutdown requested and no clients connected
# then exit the server
if ($server_shutdown && $clients_connected == 0) {
error_stderr("WebSocket server has shut down on last client disconnect");
remove_miniserv_websocket($port, $current_theme);
exit(0);
if ($serv->{'shutdown'} && $serv->{'clients_connected'} == 0) {
error_stderr("WebSocket server is shutting down on last client disconnect");
$serv->shutdown();
}
}
);
},
on_shutdown => sub {
# Shutdown the server and clean up
my ($serv) = @_;
error_stderr("WebSocket server has gracefully shut down");
remove_miniserv_websocket($port, $current_theme);
cleanup_miniserv_websockets([$port], $current_theme);
exit(0);
},
)->start;
if ($stats_running) {
error_stderr("WebSocket server failed");
}
else {
error_stderr("WebSocket server has gracefully shut down");
}
error_stderr("WebSocket server failed");
remove_miniserv_websocket($port, $current_theme);
cleanup_miniserv_websockets([$port], $current_theme);

Expand Down

0 comments on commit 5fb8be0

Please sign in to comment.