Object-Remote

 view release on metacpan or  search on metacpan

lib/Object/Remote/FatNode.pm  view on Meta::CPAN

push @non_core_non_arch, grep +(
  not (
    #some of the config variables can be empty which will eval as a matching regex
    $Config{privlibexp} ne '' && /^\Q$Config{privlibexp}/
      or $Config{archlibexp} ne '' && /^\Q$Config{archlibexp}/
      or $Config{vendorarchexp} ne '' && /^\Q$Config{vendorarchexp}/
      or $Config{sitearchexp} ne '' && /^\Q$Config{sitearchexp}/
  )
), grep !/\Q$Config{archname}/, grep !/\Q$Config{myarchname}/, keys %mods;

my @core_non_arch = grep +(
  $Config{privlibexp} ne '' && /^\Q$Config{privlibexp}/
  and not($Config{archlibexp} ne '' && /^\Q$Config{archlibexp}/
    or /\Q$Config{archname}/ or /\Q$Config{myarchname}/)
), keys %mods;

my $start = stripspace <<'END_START';
  # This chunk of stuff was generated by Object::Remote::FatNode. To find
  # the original file's code, look for the end of this BEGIN block or the
  # string 'FATPACK'
  BEGIN {
  my (%fatpacked,%fatpacked_extra);
END_START

$start .= 'my %exclude = map { $_ => 1 } (\'' . join("','", @exclude_mods) . "');\n";

my $end = stripspace <<'END_END';
  s/^  //mg for values %fatpacked, values %fatpacked_extra;

  sub load_from_hash {
    if (my $fat = $_[0]->{$_[1]}) {
      if ($exclude{$_[1]}) {
        warn "Will not pre-load '$_[1]'";
        return undef;
      }

      #warn "Handling $_[1]";
      open my $fh, '<', \$fat;
      return $fh;
    }

    #Uncomment this to find brokenness
    #warn "Missing $_[1]";
    return;
  }

  unshift @INC, sub { load_from_hash(\%fatpacked, $_[1]) };
  push @INC, sub { load_from_hash(\%fatpacked_extra, $_[1]) };

  } # END OF FATPACK CODE

  use strictures 1;
  use Object::Remote::Node;

  unless ($Object::Remote::FatNode::INHIBIT_RUN_NODE) {
    Object::Remote::Node->run(watchdog_timeout => $WATCHDOG_TIMEOUT);
  }

END_END

my %files = map +($mods{$_} => scalar do { local (@ARGV, $/) = ($_); <> }),
              @non_core_non_arch, @core_non_arch;

sub generate_fatpack_hash {
  my ($hash_name, $orig) = @_;
  return '' unless $orig;
  (my $stub = $orig) =~ s/\.pm$//;
  my $name = uc join '_', split '/', $stub;
  my $data = $files{$orig} or die $orig; $data =~ s/^/  /mg;
  $data .= "\n" unless $data =~ m/\n$/;
  my $ret = '$'.$hash_name.'{'.perlstring($orig).qq!} = <<'${name}';\n!
    .qq!${data}${name}\n!;
  return $ret;
}

# HAARG notes that ideally Object::Remote should use Module::Reader to
# pass the sources of fatpacked modules to the remote. However, it has
# some problems with more recent Perl versions, which is why we go with
# the approach below (for now)  --  EH 2025-07-20
sub propagate_fatpacked {
  my ($hash_name, $fat_hash) = @_;
  warn 'Propagating fatpacked hash' . $fat_hash;
  my @segments;
  while (my ($orig, $data) = each %{$fat_hash}) {
    (my $stub = $orig) =~ s/\.pm//;
    my $name = uc join '_', split '/', $stub;
    $data =~ s/^/  /mg;
    $data .= "\n" unless $data =~ m/\n$/;
    push @segments,
      ('$'.$hash_name.'{'.perlstring($orig).qq!} = <<'${name}';\n!
       .qq!${data}${name}\n!);
  }
  return @segments;
}

my @segments = (
  map(generate_fatpack_hash('fatpacked', $_), sort map $mods{$_}, @non_core_non_arch),
  map(generate_fatpack_hash('fatpacked_extra', $_), sort map $mods{$_}, @core_non_arch),
  (map { propagate_fatpacked('fatpacked', $_) } grep { blessed($_) and ref($_) =~ m/^FatPacked::/ } @INC),
);

#print STDERR Dumper(\@segments);
our $DATA = join "\n", $start, @segments, $end;

1;



( run in 0.931 second using v1.01-cache-2.11-cpan-7e94247ccb0 )