App-BrowserUtils

 view release on metacpan or  search on metacpan

lib/App/BrowserUtils.pm  view on Meta::CPAN

            }
        } else { # restart
            my $res_term;
          TERMINATE: {
                last unless $has_processes;
                if ($args{-dry_run}) {
                    log_info "[DRY] Terminating $browser ...";
                    $terminated{$browser}++;
                    last;
                }

                $res_term = _do_browser('terminate', $browser, users=>[$>]);
                if ($res_term->[0] != 200) {
                    log_error "Can't terminate $browser: $res_term->[0] - $res_term->[1], skipped";
                    $fail{$browser} //= "Can't terminate";
                    next;
                }

                sleep 3;

                $res_hp = _do_browser('has_processes', $browser, users=>[$>]);
                if ($res_hp->[0] != 200) {
                    log_error "Can't check whether $browser has processes (after terminatign): $res_hp->[0] - $res_hp->[1], skipped";
                    $fail{$browser} //= "Can't check for processes (after terminating)";
                    next;
                }
                $has_processes = $res_hp->[2];
                if ($has_processes) {
                    log_error "$browser still has processes after terminating, skipped";
                    $fail{$browser} //= "Still has process after terminating";
                    next;
                }
                $terminated{$browser}++;
            } # TERMINATE
        }

      START: {
            my $cmd = $args{"${browser}_cmd"} //
                $argsopt_browser_start{"${browser}_cmd"}{default};

            if ($args{-dry_run}) {
                log_info "[DRY] Starting %s (cmd: %s) ...", $browser, $cmd;
                $started{$browser}++;
                last;
            }

            log_info "Starting %s (cmd: %s) ...", $browser, $cmd;
            $outputs{$browser} = Capture::Tiny::capture_merged(
                sub { $pbs{$browser} = Proc::Background->new($cmd) });
            $started{$browser}++;
        }
    }

    my $num_started = keys %started;
    if ($num_started == 0) {
        return [304,
                $num_start_requests ? "All browsers already have processes" :
                    "Not ${which_action}ing any browsers"];
    }

    my (%alive, %not_alive);
    if ($args{-dry_run}) {
        %alive = %started;
    } else {
        for my $wait_time (2, 5, 10) {
            %alive = ();
            %not_alive = ();
            log_trace "Checking if the started browsers are alive ...";
            for my $browser (keys %pbs) {
                if ($pbs{$browser}->alive) {
                    $alive{$browser}++;
                } else {
                    $not_alive{$browser}++;
                }
            }
            last if scalar(keys %alive) == $num_started;
        }
    }

    my $num_alive = keys %alive;
    my $num_not_alive = keys %not_alive;

    my $status;
    my $reason;
    my $msg;
    my $verb_started = $which_action eq 'restart' ? 'Started/restarted' : 'Started';
    if ($num_alive == $num_started) {
        $status = 200;
        $reason = "OK";
        $msg = "$verb_started ".join(", ", sort keys %alive);
    } elsif ($num_alive == 0) {
        $status = 500;
        $reason = $msg = "Can't start any browser (".join(", ", %not_alive).")";
    } else {
        $status = 200;
        $reason = "OK";
        $msg = "$verb_started ".join(", ", sort keys %alive)."; but failed to start ".
            join(", ", sort keys %not_alive);
    }

    $fail{$_} //= "Can't start" for keys %not_alive;

    [$status, $msg, undef, {
        'func.outputs' => \%outputs,
        ($which_action eq 'start' ? ('func.has_processes' => [sort keys %has_processes]) : ()),
        'func.started' => [sort grep {!$terminated{$_}} keys %alive],
        ($which_action eq 'restart' ? ('func.restarted' => [sort grep {$terminated{$_}} keys %alive]) : ()),
        'func.fail' => [sort keys %fail],
    }];
}

$SPEC{start_browsers} = {
    v => 1.1,
    summary => "Start browsers",
    description => <<'MARKDOWN',

For each of the requested browser, check whether browser processes (that run as
the current user) exist and if not then start the browser. If browser processes
exist, even if all are paused, then no new instance of the browser will be
started.

when starting each browser, console output will be captured and returned in
function metadata. Will wait for 2/5/10 seconds and check if the browsers have
been started. If all browsers can't be started, will return 500; otherwise will
return 200 but report the browsers that failed to start to the STDERR.

Example on the CLI:

    % start-browsers --start-firefox

To customize command to use to start:

    % start-browsers --start-firefox --firefox-cmd 'firefox -P myprofile'

MARKDOWN
    args => {
        # args_common is not relevant here, for now (unless we want to start
        # browsers as other users)

        %argsopt_browser_start,
        %argsopt_browser_cmd,
        %argopt_quiet,
    },
    features => {
        dry_run => 1,
    },
};
sub start_browsers {
    _start_or_restart_browsers('start', @_);
}

$SPEC{restart_browsers} = {
    v => 1.1,
    summary => "Restart browsers",
    description => <<'MARKDOWN',

For each of the requested browser, first check whether browser processes (that
run the current user) exist. If they do then terminate the browser first. After
that, start the browser again.

Example on the CLI:



( run in 0.687 second using v1.01-cache-2.11-cpan-df04353d9ac )