package POEDaemon::System::Reload; use strict; use warnings FATAL => 'all'; no warnings 'redefine'; use POE; use POEDaemon; eval { require Time::Stopwatch; }; my $have_time_stopwatch = 1 unless $@; sub states { return $_[0], [qw( reload )]; } sub reload { my ($kernel, $session, $heap, $args) = @_[KERNEL, SESSION, HEAP, ARG0]; log_enabled && logline 'event fired'; my $stopwatch; tie $stopwatch, 'Time::Stopwatch' if $have_time_stopwatch; $heap->{reload}->{count} = 0 unless defined $heap->{reload}->{count}; $heap->{reload}->{count}++; my $wheel_id = $args->{source_wheel_id}; my $subcmd = $args->{subcmd} || ''; my $old_states = {}; foreach my $state (keys %{$session->[POE::Session::SE_STATES]}) { next if $state =~ /^POE::/i; $old_states->{$state} = 1; } my $config_old = cfg; my $module_modified_tags_old = $heap->{module_modified_tags} || {}; $module_modified_tags_old = {} if $subcmd =~ /force/; my $load_modules_result = POEDaemon::load_modules 'reload', $module_modified_tags_old; my $modules = $load_modules_result->{modules} || []; my @errors = @{$load_modules_result->{errors} || []}; my $poe_state_modules = $load_modules_result->{poe_state_modules} || {}; my $poe_state_modules_arrayref = $load_modules_result->{poe_state_modules_arrayref} || []; my $statelist = $load_modules_result->{statelist} || {}; my $module_modified_tags = $load_modules_result->{module_modified_tags} || {}; my $modules_modified = $load_modules_result->{modules_modified} || []; my $modules_modified_hashref = $load_modules_result->{modules_modified_hashref} || {}; my $config_load_error = $load_modules_result->{load_modules_result}; $heap->{poe_state_modules} = $poe_state_modules; $heap->{statelist} = $statelist; $heap->{module_modified_tags} = $module_modified_tags; foreach my $module_item (@$poe_state_modules_arrayref) { foreach my $module (keys %$module_item) { foreach my $state (@{$module_item->{$module}}) { if ($modules_modified_hashref->{$module}) { log_enabled && logline "kernel->state('%s' => '%s')", $state, $module; $kernel->state($state => $module); } delete $old_states->{$state}; } } } if ($config_load_error) { unless (%{$heap->{reload}->{old_config} || {}}) { $heap->{reload}->{old_config} = $config_old; } push @errors, 'config load error, using old config'; } else { delete $heap->{reload}->{old_config}; } my $config_new = cfg; my $output; if (@errors && log_enabled) { my $i = 0; foreach my $error (@errors) { $i++; log_enabled && logline "error #%s: %s", $i, $error; } } $output = sprintf "RELOAD%s #%s %s%s%s%s", ($subcmd ? sprintf " %s", $subcmd : ''), $heap->{reload}->{count}, (@errors ? 'error' : 'ok'), ($have_time_stopwatch ? sprintf " time=%.3fms", $stopwatch * 1000 : ''), (@$modules_modified ? sprintf " %s", join ' ', @$modules_modified : ''), (@errors ? sprintf "\n%s", join "\n", @errors : ''); $heap->{reload}->{old_states} = $old_states; if (%$old_states) { my @old_states_list = sort keys %$old_states; log_enabled && logline "found old / unused states: %s", join(' ', @old_states_list); if ($subcmd =~ /clear/) { foreach my $state (@old_states_list) { log_enabled && logline "clear old state: kernel->state('%s')", $state; $kernel->state($state); } $output = sprintf "%s\nold states cleared: %s", $output, join(' ', @old_states_list); } else { $output = sprintf "%s\nsome states FAILED: %s", $output, join(' ', @old_states_list); } } unless (@errors || %$old_states) { unless (dumper_compare $config_old, $config_new) { $output = sprintf "%s\nconfiguration changed", $output; unless (dumper_compare $config_old->{eventmap}, $config_new->{eventmap}) { $output = sprintf "%s\neventmap changed", $output; #foreach my $wheel_id (keys %{$heap->{tcpserver}->{connections}}) #{ # next unless $heap->{tcpserver}->{connections}->{$wheel_id}; # # # delete $heap->{tcpserver}->{connections}->{$wheel_id}->{pins_configured}; #} } } } log_enabled && logline "output:\n%s", $output; my $prod_log_output = $output; foreach ($prod_log_output) { s/\s+/\x20/g; s/^\s+//; s/\s+$//; s/^RELOAD/reload/; } prod_log_enabled && prod_logline $prod_log_output; return unless $wheel_id && $output; $kernel->yield(tcpserver_output => { wheel_id => $wheel_id, output => $output, }); } 1;