App-EventStreamr/lib/App/EventStreamr/Status.pm
package App::EventStreamr::Status;
use Method::Signatures;
use JSON;
use Scalar::Util::Reftype;
use Moo;
use namespace::clean;
# ABSTRACT: A status object
our $VERSION = '0.5'; # VERSION: Generated by DZP::OurPkg:Version
#my $ConfigRef = sub {
# croak "config isn't a 'App::EventStreamr::Config' object!" unless reftype( $_[0] )->class eq "App::EventStreamr::Config";
#};
has 'status' => ( is => 'rw' );
has 'config' => ( is => 'rw' );
method starting($id,$type) {
# TODO: Logging here once log role exists
$self->{status}{$id}{runcount} = $self->{status}{$id}{runcount} ? $self->{status}{$id}{runcount} + 1 : 1;
$self->{status}{$id}{running} = 0;
$self->{status}{$id}{status} = "starting";
$self->{status}{$id}{state} = "soft";
$self->{status}{$id}{type} = $type;
$self->{status}{$id}{id} = $id;
$self->post_status();
}
method waiting($id,$type,$status) {
# TODO: Logging here once log role exists
$self->{status}{$id}{status} = $status;
$self->{status}{$id}{state} = "wait";
$self->{status}{$id}{type} = $type;
$self->{status}{$id}{id} = $id;
$self->post_status();
}
method stopping($id,$type) {
# TODO: Logging here once log role exists
$self->{status}{$id}{status} = "stopping";
$self->{status}{$id}{state} = "soft";
$self->{status}{$id}{type} = $type;
$self->{status}{$id}{id} = $id;
$self->post_status();
}
method restarting($id,$type) {
# TODO: Logging here once log role exists
$self->{status}{$id}{status} = "restarting";
$self->{status}{$id}{state} = "soft";
$self->{status}{$id}{type} = $type;
$self->{status}{$id}{id} = $id;
$self->post_status();
}
method set_state($state,$id,$type) {
if (defined $self->{status}{$id}{running} &&
$self->{status}{$id}{running} != $state) {
# TODO: Logging here once log role exists
$self->{status}{$id}{runcount} = 0;
$self->{status}{$id}{running} = $state;
$self->{status}{$id}{status} = $state ? 'started' : 'stopped';
$self->{status}{$id}{state} = "hard";
$self->{status}{$id}{timestamp} = time;
$self->{status}{$id}{type} = $type;
$self->{status}{$id}{id} = $id;
$self->post_status();
return 1;
}
return 0;
}
method threshold($id,$type,$status = "failed") {
$self->{status}{$id}{timestamp} = time if (! $self->{status}{$id}{timestamp});
my $age = time - $self->{status}{$id}{timestamp};
if ( defined $self->{status}{$id}{runcount} &&
($self->{status}{$id}{runcount} > 5 && (time % 10) != 0) ) {
$self->{status}{$id}{status} = $status;
$self->{status}{$id}{state} = "hard";
$self->{status}{$id}{type} = $type;
$self->{status}{$id}{id} = $id;
$self->info("$id failed to start (count=".$self->{status}{$id}{runcount}.", died=$age secs ago)");
$self->post_status();
return 1;
}
return 0;
}
method post_status {
if ($self->config) {
my $status;
$status->{status} = $self->{status};
$status->{macaddress} = $self->config->macaddress;
$status->{nickname} = $self->config->nickname;
my $json = to_json($status);
my %post_data = (
content => $json,
'content-type' => 'application/json',
'content-length' => length($json),
);
my $post = $self->config->http->post(
"http://".$self->config->{mixer}{host}.":3000/status/".$self->config->macaddress,
\%post_data,
);
$self->debug("Status posted to http://".$self->config->{mixer}{host}.":3000/status/".$self->config->macaddress);
$self->debug({filter => \&Data::Dumper::Dumper,
value => $post}) if ($self->is_debug());
if ( $self->config->controller ) {
# The Frontend doesn't like empty objects..
# TODO: Fix the frontend
foreach my $key (keys %{$self->{status}}) {
if (! defined $self->{status}{$key}{id}) {
delete $self->{status}{$key};
}
}
my $data;
$data->{key} = "status";
$data->{value} = $self->{status};
%post_data = (
content => to_json($data),
headers => {
'station-mgr' => 1,
'Content-Type' => 'application/json',
}
);
$post = $self->config->http->post(
$self->config->controller."/api/station/".$self->config->macaddress."/partial",
\%post_data,
);
$self->debug({filter => \&Data::Dumper::Dumper,
value => $post}) if ($self->is_debug());
$self->info("Status posted to ".$self->config->controller."/api/station/".$self->config->macaddress."/partial");
}
}
}
with('App::EventStreamr::Roles::Logger');
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
App::EventStreamr::Status - A status object
=head1 VERSION
version 0.5
=head1 SYNOPSIS
This package provides core status notification methods.
=head1 DESCRIPTION
Whilst at it's core EventStreamr Starts/Stops processes, the ability
to notify when something goes wrong and can't be fixed by itself is
the primary job.
It provides some convenience methods to keep the Run/Stop code nice
and simple. It also is intended to be passed around as a reference
to ensure state is maintained across the application.
=head1 AUTHOR
Leon Wright < techman@cpan.org >
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2014 by Leon Wright.
This is free software, licensed under:
The GNU Affero General Public License, Version 3, November 2007
=cut