RZ

001: # DemandRetriever.pl # mediates between data driven and demand driven processes
002:
003: use strict;
004:
005: local( $0 ) = "DemandRetriever";
006:
007: require "GetoptSynthesize.pl";
008:
009: local( $::verbose ) = GetoptSynthesize::verbosity();
010: local( $::debug ) = GetoptSynthesize::debug();
011:
012: ######## ######## ######## ######## ######## ######## ######## ######## ########
013: ######## ######## ######## ######## ######## ######## ######## ######## ########
014:
015: ######## open transaction ########
016:
017: {
018:     no warnings qw(once);
019:     print STDERR "  get $GetoptSynthesize::url\n" if $::debug;
020: }
021:
022: local( $^F ) = 1<<31 - 1; # fudge # want our file visible in the exec'ed code
023:
024: ######## return from 'Reconstituter subprocesses ########
025:
026: open( my $RECONSTITUTED, "+>", undef ) or die "Can't open a tempfile\n";
027:
028: ######## fork and exec C++ demand mediator ########
029:
030: {
031:     my ( $RANGE, $REMOTE );
032:     pipe my $DataRemoteRetrieverREMOTE, $REMOTE;
033:     {
034:         print STDERR "  scan <- givens\n" if $::debug;
035:
036:         my @openscanfiles; # open scanfiles in main proc for pretty messages
037:         while ( GetoptSynthesize::openh( given => my $SCANFILE ) ) {
038:             push @openscanfiles, $SCANFILE;
039:         }
040:
041:         unless ( my $pid = open( $RANGE, "-|" ) ) {
042:             defined $pid or die "Can't start mediator child process\n";
043:
044:             close $REMOTE;
045:
046:             # may use inherited STDIN
047:             # use STDOUT {to $RANGE}
048:             # use DataRemoteRetriever::REMOTE
049:             # use $RECONSTITUTED
050:             # use @openscanfiles
051:
052:             no warnings qw(once); 
053:             exec { $INC[0]."/DemandMediator.gateway" } (
054:                 $0,
055:                 "-I", $INC[0],
056:                 1,
057:                 fileno( $DataRemoteRetrieverREMOTE ),
058:                 fileno( $RECONSTITUTED ),
059:                 $::debug,
060:                 $::verbose,
061:                 map( ("--givenfd" => fileno( $_ )), @openscanfiles ),
062:             ); die "Mediator failure: $!\n";
063:
064:             # implied exit closing STDIN
065:             # implied exit closing STDOUT
066:             # implied exit closing @openscanfiles
067:             # implied exit closing $RECONSTITUTED
068:             # implied exit closing DataRemoteRetriever::REMOTE
069:         }
070:
071:         # scanfiles would close automatically - explicitly for nice messages
072:         while ( my $SCANFILE = pop @openscanfiles ) {
073:             GetoptSynthesize::closeh( $SCANFILE );
074:         }
075:     }
076:
077:     {
078:         local( $SIG{ PIPE } );
079:         my $OLDOUT = select $REMOTE;
080:         eval {
081:             $SIG{ PIPE } = sub { close; die "SIGPIPE\n" };
082:             close $DataRemoteRetrieverREMOTE;
083:
084:             require "BlockRetrieval.pl";
085:
086:             $| = 1; # forces output to flush after each write
087:             while ( <$RANGE> ) {
088:                 chomp;
089:                 m{^bytes=\d+-\d+(?:,\d+-\d+)*$} or die;
090:                 print STDERR "($_)" if $::debug + $::verbose > 2;
091:                 BlockRetrieval::retrieverange( $_ );
092:             }
093:
094:             close;
095:         } or ( $@ eq "SIGPIPE\n" ) or die $@;
096:         select $OLDOUT;
097:     }
098:     
099:     close $RANGE;
100:     $? and die "Mediator failed with error $?";
101: }
102:
103: ######## commit transaction ########
104:
105: GetoptSynthesize::backh( destination => );
106:
107: GetoptSynthesize::openh( destination => my $DESTINATION );
108:
109: print STDERR "  tempfiles -> destination\n" if $::debug;
110:
111: while( read( $RECONSTITUTED, my $bk, 8192 ) ) {
112:     print $DESTINATION $bk;
113: }
114:
115: GetoptSynthesize::closeh( $DESTINATION );
116: close $RECONSTITUTED;
117:
118: ######## ######## ######## ######## ######## ######## ######## ######## ########
119:
120: # DemandRetriever.pl # mediates between data driven and demand driven processes