App-EventStreamr

 view release on metacpan or  search on metacpan

bin/station-mgr.pl  view on Meta::CPAN

  return;
}

## Ingest
sub ingest {
  if ($self->{dvswitch}{running} == 1) {
    foreach my $device (@{$self->{config}{devices}}) {
      # Set Role
      $device->{role} = "ingest";

      if ($device->{type} eq "dv") {
        # Check dv exists
        if (-e $self->{devices}{dv}{$device->{id}}{path}) {
          run_stop($device);
        # If we're restarting we should refresh the devices and try again
        } elsif ($self->{config}{device_control}{$device->{id}}{run} == 1) {
          $logger->warn("$device->{id} has been disconnected");
          # It's not ideal, but dvgrab hangs if no camera exist. devmon will restart it when it's plugged in again.
          $self->{config}{device_control}{$device->{id}}{run} = 0;
          run_stop($device);

          # Set status
          $self->{device_control}{$device->{id}}{timestamp} = time;
          $self->{status}{$device->{id}}{running} = 0;
          $self->{status}{$device->{id}}{status} = "disconnected";
          $self->{status}{$device->{id}}{state} = "hard";
          post_config();
        } elsif ($self->{config}{device_control}{$device->{id}}{run} == 2) {
          $logger->warn("$device->{id} has been restarted, refreshing devices");
          $self->{devices} = $devices->all();
          post_config();
          run_stop($device);
        } 
      } else {
        run_stop($device);
      }
    }
  }
  return;
}

## Mixer
sub mixer {
  my $device;
  $device->{role} = "mixer";
  $device->{id} = "dvswitch";
  $device->{type} = "mixer";
  run_stop($device);
  
  my $loop;
  if ($self->{config}{mixer}{loop} && $self->{dvswitch}{running}) {
    if (-e $self->{config}{mixer}{loop}) {
      $loop->{role} = "ingest";
      $loop->{id} = $self->{config}{mixer}{loop};
      $loop->{type} = "file";
      run_stop($loop);
    } else {
      # Set status
      $self->{device_control}{$loop->{id}}{timestamp} = time;
      $self->{status}{$loop->{id}}{running} = 0;
      $self->{status}{$loop->{id}}{status} = "file_not_found";
      $self->{status}{$loop->{id}}{state} = "hard";
      $self->{status}{$loop->{id}}{name} = "standby loop";
      post_config();
    }
  }
  return;
}

## Stream
sub stream {
  my $device;
  $device->{role} = "stream";
  $device->{id} = $self->{config}{stream}{stream};
  $device->{type} = "stream";
  run_stop($device);
  return;
}

## Record
sub record {
  my $device;
  $device->{role} = "record";
  $device->{id} = "record";
  $device->{type} = "record";

  # Get path (date + room)
  unless ($self->{device_control}{$device->{id}}{recordpath}) {
    $self->{device_control}{$device->{id}}{recordpath} = set_path($self->{config}{record_path});
    $logger->info("Path for $device->{id}: $self->{device_control}{$device->{id}}{recordpath}");
  }
  
  # Create the path if it doesn't exist
  unless(-d "$self->{device_control}{$device->{id}}{recordpath}") {
    my $result = eval { make_path("$self->{device_control}{$device->{id}}{recordpath}") };
    
    if ($result) {
      $logger->info("Path created for $device->{id}: $self->{device_control}{$device->{id}}{recordpath}");
      post_config();
    } else {

      # if above threshold then slow down attempts to every 10 seconds
      if ( $self->{device_control}{$device->{id}}{runcount} > 5 && (time % 10) != 0 ) {
        return;
      }

      $logger->error("Path creation failed for $device->{id}: $self->{device_control}{$device->{id}}{recordpath}");
      
      $self->{device_control}{$device->{id}}{runcount}++;
      # Set device status
      $self->{status}{$device->{id}}{type} = $device->{type};
      $self->{status}{$device->{id}}{timestamp} = time;
      $self->{status}{$device->{id}}{running} = 0;
      $self->{status}{$device->{id}}{status} = "not_writeable";
      $self->{status}{$device->{id}}{state} = "hard";
      post_config();
      
      return;
    }
  }

  if ($self->{dvswitch}{running} == 1) {
    run_stop($device);
  }
  sync();
  return;
}

## sync 
sub sync {
  my $device;
  $self->{device_commands}{sync}{command} = "$Bin/station-sync.sh $self->{device_control}{record}{recordpath} $self->{config}{sync}{host} $self->{config}{sync}{path} $self->{config}{room}";
  $device->{role} = "sync";
  $device->{id} = "sync";
  $device->{type} = "internal";
  if ($self->{config}{sync}{host} && $self->{config}{sync}{path}) {
    run_stop($device);
  } else {
    # set status
    $self->{status}{$device->{id}}{type} = $device->{type};
    $self->{status}{$device->{id}}{timestamp} = time;
    $self->{status}{$device->{id}}{running} = 0;
    $self->{status}{$device->{id}}{status} = "not_configured";
    $self->{status}{$device->{id}}{state} = "hard";
  }
  return;
}

# run, stop or restart a process 
sub run_stop {
  my ($device) = @_;
  my $time = time;

  # Build command for execution and save it for future use
  unless ($self->{device_commands}{$device->{id}}{command}) {
    given ($device->{role}) {
      when ("ingest")   { 
        $self->{device_commands}{$device->{id}}{command} = ingest_commands($device->{id},$device->{type});
        $logger->info("Command for $device->{id} - $device->{type}: $self->{device_commands}{$device->{id}}{command}");
      }
      when ("mixer")    { 
        $self->{device_commands}{$device->{id}}{command} = mixer_command(); 
        $logger->info("Command for $device->{id} - $device->{type}: $self->{device_commands}{$device->{id}}{command}");
      }
      when ("stream")   { 
        $self->{device_commands}{$device->{id}}{command} = stream_command($device->{id},$device->{type}); 
        $logger->info("Command for $device->{id} - $device->{type}: $self->{device_commands}{$device->{id}}{command}");
      }
      when ("record")   { 
        $self->{device_commands}{$device->{id}}{command} = record_command($device->{id},$device->{type}); 
        $logger->info("Command for $device->{id} - $device->{type}: $self->{device_commands}{$device->{id}}{command}");
      }
    }
  }

  # If we're supposed to be running, run.
  if (($self->{config}{run} == 1 && 
  (! defined $self->{config}{device_control}{$device->{id}}{run} || $self->{config}{device_control}{$device->{id}}{run} == 1)) ||
  $device->{type} eq 'internal') {
    # The failed service check depends on a run flag being set, if we got here it should be 1.
    $self->{config}{device_control}{$device->{id}}{run} = 1;

    # Get the running state + pid if it exists
    my $state;
    if ($self->{device_control}{$device->{id}}{pid}) {
      $state = $utils->get_pid_state($self->{device_control}{$device->{id}}{pid}); 
    } else {
      $state = $utils->get_pid_command($device->{id},$self->{device_commands}{$device->{id}}{command},$device->{type}); 
    }

    unless ($state->{running}) {

      # notice process is down, record timestamp when it went down
      if ( ! defined $self->{device_control}{$device->{id}}{timestamp} ) {
        $self->{device_control}{$device->{id}}{timestamp} = $time;
        $self->{device_control}{$device->{id}}{runcount} = 0;

        $self->{status}{$device->{id}}{running} = 0;
        $self->{status}{$device->{id}}{status} = "starting";
        $self->{status}{$device->{id}}{state} = "soft";
        $self->{status}{$device->{id}}{type} = $device->{type};
        $self->{status}{$device->{id}}{timestamp} = $self->{device_control}{$device->{id}}{timestamp};



( run in 1.134 second using v1.01-cache-2.11-cpan-39bf76dae61 )