Tripletail

 view release on metacpan or  search on metacpan

lib/Tripletail/FileSentinel.pm  view on Meta::CPAN

	if(!$_INSTANCE) {
		$_INSTANCE = $class->_new(@_);
	}

	$_INSTANCE;
}

sub __install {
	my $this = shift;

	$TL->setHook('postRequest', _HOOK_PRIORITY, sub { $this->__postRequest });
}

sub watch {
	my $this = shift;
	my $fpath = shift;
	$fpath = File::Spec->rel2abs($fpath);

	my $lastmod = (stat($fpath))[9];
	if(!$lastmod) {
		die __PACKAGE__."#watch: failed to stat [$fpath]: $! (ファイルをstatできませんでした)\n";
	}

    if ($TL->INI->get(TL => filelog => 'update') eq 'full') {
        $TL->log(
            __PACKAGE__,
            sprintf(
                'Watching file [%s]: last modified time: [%s]',
                $fpath,
                scalar(localtime($lastmod))
               )
           );
    }

	$this->{lastmod}{$fpath} = $lastmod;
	$this;
}

sub autoWatch {
	my $this = shift;
	my $include = shift;
	my $exclude = shift;
	local $_;

	return unless defined $include || defined $exclude;

	my @targets = values %INC;
	@targets = grep  m{$include}, @targets if $include;
	@targets = grep !m{$exclude}, @targets if $exclude;

	foreach ( @targets ) {
		$TL->log(__PACKAGE__, " autoWatch(): $_");
		$this->watch($_);
	}

	$this;
}

sub _new {
	my $class = shift;
	my $this = bless {} => $class;

	$this->{lastmod} = {}; # {file path => epoch}

	if(defined($0)) {
		$this->watch($0);
	}
	my $filename = $TL->INI->getFilePath;
	if(defined($filename)) {
		$this->watch($filename);
	}

	$this->autoWatch(
		$TL->INI->get(FileSentinel => autowatch_include => undef),
		$TL->INI->get(FileSentinel => autowatch_exclude => undef)
	);

	$this;
}

sub __postRequest {
	my $this = shift;

	while(my ($fpath, $lastmod) = each %{$this->{lastmod}}) {
		my $current = (stat($fpath))[9];
		if(!$current) {
			die __PACKAGE__."#postRequest: failed to stat [$fpath]: $! (ファイルをstatできませんでした)\n";
		}

		if($current != $lastmod) {
			my $time = localtime($current);

			$TL->log("File Update: file [$fpath] has been updated at [$time]");
			$TL->_fcgi_restart(1);
		}
	}
}


__END__

=encoding utf-8

=head1 NAME

Tripletail::FileSentinel - ファイルの更新の監視

=head1 SYNOPSIS

  my $fsenti = $TL->getFileSentinel;

  $fsenti->watch('/etc/passwd');
  $fsenti->watch('/var/log/wtmp');

=head1 DESCRIPTION

FCGI モードの際に、特定のファイルが更新されたかどうかを調べて、
更新を検出した場合にプロセスを再起動する。このモジュールは
FCGI モードで自動的に使用され、FCGI モードでない時には使用されない。

=head2 METHODS



( run in 0.881 second using v1.01-cache-2.11-cpan-2e0ccfb7a10 )