Grid-Request

 view release on metacpan or  search on metacpan

lib/Grid/Request/JobFormulator.pm  view on Meta::CPAN


    my @invocations =  _assemble_invocations($blocksize, $executable, \@arg_groups);

    return wantarray ? @invocations : \@invocations;
}

sub _limit_arguments {
    my $arg_group_ref = shift;
    my @arg_groups = @$arg_group_ref;
    # Chop all the arg_groups according to the group with the smallest size
    my $min;
    foreach my $group (@arg_groups) {
        # $group is an array ref here
        my $current_size = scalar(@$group);
        if (defined $min) {
            if ($current_size < $min) {
                $min = $current_size;
            }
        } else {
            $min = $current_size;
        }
    }
    $logger->debug("Determined that the number of times we can iterate with these arguments is $min.");

    # Now that we know the minimum size, we can limit each group
    my @limited_groups;
    my $group_number = 0;
    foreach my $group (@arg_groups) {
        $group_number++;
        my $size = scalar(@$group);
        if ($size > $min) {
            # Okay, this group is too big. Cut it down to size
            $logger->debug("Cutting argument group number $group_number down to $min from $size.");
            # Change the array size by assigning to $#ARRAY
            my @lesser = @$group;
            $#lesser = $min - 1;
            $group = \@lesser;
        }
        push (@limited_groups, $group);
    }
    return wantarray ? @limited_groups : \@limited_groups;
}

sub _assemble_invocations {
    $logger->debug("In _assemble_invocations.");
    my ($blocksize, $executable, $arg_group_ref) = @_;
    my ($success, $failed) = (0,0);
    my @invocations = ();

    my $group_size = scalar @$arg_group_ref;
    $logger->debug("The number of arguments each invocation of $executable will have: $group_size");

    if ( $group_size > 0 ) {
        # Which worker invocation the assembled invocations are for.
        # This module produces invocations for all the tasks that will be launched
        # so we have to replace all $Index occurrences with the right number. Block size
        # dictates how many invocations per task...
        my $task_id = 1; 
        my $block_index = 1; # Initialize a counter to iterate over the blocksize with.

        $logger->debug("Assembling iterations for task ID $task_id.");
        
        # Length of the various argument arrays should all be the same, so we'll just use
        # the length of the first one.
        my $arg_length = scalar(@{ $arg_group_ref->[0] });
        
        # This loop is to iterate across the argument arrays
        for (my $arg_index = 0; $arg_index < $arg_length; $arg_index++) {
            my @exec = ($executable);

            for (my $group_index = 0; $group_index < $group_size; $group_index++) {
                my $arg = $arg_group_ref->[$group_index]->[$arg_index];

                # Replace $(Index) with the task id.
                $arg =~ s/\$\(Index\)/$task_id/g;
                
                push(@exec, $arg);
                if ($block_index == $blocksize) {
                    $task_id++;
                    $block_index = 1;
                } else {
                    $block_index++;
                }
            }

            push(@invocations, \@exec);
        }
    } else {
        $logger->warn("No arguments! Just invoking the configured executable with no args.");
        push(@invocations, [ $executable ])
    }

    return wantarray ? @invocations : \@invocations;
}

sub _get_arguments_for_param {
    my $param_string = shift;
    my $arg_ref;
    # Use the Grid::Request::Param class to build a param and extract the type. 
    my $param = Grid::Request::Param->new($param_string);
    my $type = uc($param->type());
    my $value = $param->value();
    my $key = $param->key();
    
    # This should be dynamic. Dynamically load a module that computes the array
    # at runtime.
    if ($type eq "PARAM") {
        # This is a special case. We simply return the param string scalar,
        # so that we can later substitute it with the exact argument as
        # many times as necessary.
        $arg_ref = $param_string;
    } elsif ($type eq "DIR") {
        $arg_ref = _get_dir_args($value, $key);
    } elsif ($type eq "FILE") {
        $arg_ref = _get_file_args($value, $key);
    } else {
        # Possibly, try a dynamic load of a module
        Grid::Request::Exception->throw("Unrecognized parameter type of \"$type\".");
    }

    return $arg_ref;



( run in 0.539 second using v1.01-cache-2.11-cpan-71847e10f99 )