Commit e0eb32ab authored by Karl Kornel's avatar Karl Kornel
Browse files

Do proper select/read loop for the drive download

Having IPC::open3 write directly the output file is not as easy as
I'd like.  So, we have to do it ourselves.  But, since we have to
keep an eye on both the output *and* the error, we have to do a
proper select()/read() loop.
parent dc939d51
Loading
Loading
Loading
Loading
+36 −14
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ use warnings;
use Cwd;
use File::Copy;
use FindBin qw($RealBin $RealScript);
use IO::Select;
use IPC::Open3;
use Symbol qw(gensym);

@@ -662,8 +663,8 @@ sub drive_run {
    # Open our output file
    # NOTE: We DO overwrite files here, so it's up to the caller to
    # ensure that the file is OK to override.
    my $output_handle;
    open($output_handle, '>', $output_path) or do {
    my $output_file;
    open($output_file, '>', $output_path) or do {
        dolog(<<"EOF");
There was a problem opening the samplesheet file for writing!
The file we tried to write to: $output_path
@@ -714,6 +715,7 @@ EOF
		email_failure('Problem runnig the drive command', 'run',
			      $RUNFOLDER, "$RealBin/email-recipients.txt",
			      $LOGPATH, \$LOG, $RealBin, $RealScript);
        return undef;
    }
    close($search_inhandle);

@@ -771,16 +773,14 @@ EOF
	dolog("Drive download command output:\n");
	dolog("==========================================================\n");

	# Spawn the downlaod command
    # Remember, $output_handle was opened up a while ago.
    # We'll let IPC::open3 take care of writing to the file directly.
	# Spawn the downlaod command.
	my $input_handle;
    my $output_id = '&>' . fileno($output_handle);
    my $output_handle;
    my $error_handle = gensym();
	my $drive_buffer = '';
	my $drive_pid;
	eval {
		$drive_pid = open3($input_handle, $output_id, $error_handle,
		$drive_pid = open3($input_handle, $output_handle, $error_handle,
                        @drive_options);
	};
	if ($@) {
@@ -795,18 +795,40 @@ EOF
	}
	close($input_handle);

	# Send any stderr to the log, and then clean up
	while (read($error_handle, $drive_buffer, 10)) {
		dolog($drive_buffer);
		$drive_buffer = '';
    # Start processing program output
    my $sel = new IO::Select;
    $sel->add($output_handle, $error_handle);
    while (my @ready_handles = $sel->can_read()) {
        foreach my $handle (@ready_handles) {
            # Read the line
            my $line = <$handle>;
            if (!defined($line)) {
                # If we got undef, then that's an EOF.  So the stream's closed.
                # Remove the handle from the list, and go to the next.
                $sel->remove($handle);
                next;
            }

            # Either send the output to file, or send the output to the log.
            if ($handle == $output_handle) {
                print $output_file $line;
            }
            else {
                dolog($line);
            }
        } # Done looking each ready handle.
    }
    # At this point, there are no more handles to read.

	# Clean up!
	waitpid($drive_pid, 0);
	my $drive_exit_code = $? >> 8;
	close($error_handle);
    close($output_handle);
    close($output_file);

	# Get and return the exit code
	my $drive_exit_code = $? >> 8;
	dolog("==========================================================\n");
	dolog("The drive program returned exit code $drive_exit_code\n");
	dolog("The drive download program returned exit code $drive_exit_code\n");
	return $drive_exit_code;
}