MOON
Server: Apache
System: Linux server1.studioinfinity.com.br 2.6.32-954.3.5.lve1.4.90.el6.x86_64 #1 SMP Tue Feb 21 12:26:30 UTC 2023 x86_64
User: artinside (517)
PHP: 7.4.33
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //usr/local/share/perl5/Cpanel/TaskQueue/ChildProcessor.pm
package Cpanel::TaskQueue::ChildProcessor;

use strict;

#use warnings;
use base 'Cpanel::TaskQueue::Processor';
use Cpanel::TaskQueue::Scheduler;

our $VERSION = 0.307;

{

    sub get_child_timeout {
        my ($self) = @_;
        return;
    }

    sub get_reschedule_delay {
        my ( $self, $task ) = @_;

        return 15 * 60;
    }

    sub retry_task {
        my ( $self, $task, $delay ) = @_;
        $delay ||= $self->get_reschedule_delay($task);

        $task->decrement_retries();
        if ( $task->retries_remaining() and $task->get_userdata('sched') ) {
            my $s = Cpanel::TaskQueue::Scheduler->new( { token => $task->get_userdata('sched') } );

            # This will either succeed or exception.
            $s->schedule_task( $task, { delay_seconds => $delay } );
        }

        return;
    }

    sub process_task {
        my ( $self, $task, $logger ) = @_;
        my $pid = fork();

        $logger->throw( "Unable to start a child process to handle the '" . $task->command() . "' task\n" )
          unless defined $pid;

        # Parent returns
        return $pid if $pid;

        my $timeout = $self->get_child_timeout() || $task->child_timeout();
        my $oldalarm;
        eval {
            local $SIG{'CHLD'} = 'DEFAULT';
            local $SIG{'ALRM'} = sub { die "timeout detected\n"; };
            $oldalarm = alarm $timeout;
            $self->_do_child_task( $task, $logger );
            alarm $oldalarm;
        };
        my $ex = $@;
        if ($ex) {
            alarm $oldalarm;
            if ( $ex eq "timeout detected\n" ) {
                eval {

                    # TODO: consider adding another timeout in case this handling
                    # locks up.
                    $self->_do_timeout($task);

                    # Handle retries
                    $self->retry_task($task);
                };

                # Don't throw, we want to exit instead.
                if ($@) {
                    $logger->warn($@);
                    exit 1;
                }
            }
            else {

                # Don't throw, we want to exit instead.
                $logger->warn($ex);
                exit 1;
            }
        }
        exit 0;
    }

    sub _do_timeout {
        my ( $self, $task ) = @_;

        return;
    }

    sub _do_child_task {
        my ( $self, $task, $logger ) = @_;

        $logger->throw("No child task defined.\n");
    }
}

1;