Platon Technologies
neprihlásený Prihlásiť Registrácia
SlovakEnglish
open source software development oslavujeme 10 rokov vývoja otvoreného softvéru! Sobota, 14. jún 2025

Súbor: [Platon] / perl-modules / Platon / FastCGI / Restart.pm (stiahnutie)

Revízia 1.7, Thu Sep 8 23:34:24 2005 UTC (19 years, 9 months ago) by rajo


Zmeny od 1.6: +3 -2 [lines]

Fix.

#
# Platon/FastCGI/Restart.pm - check, if FastCGI script or user/system
#                             modules was modified
#
# Developed by Lubomir Host 'rajo' <rajo AT platon.sk>
# Copyright (c) 2004 Platon SDG, http://platon.sk/
# Licensed under terms of GNU General Public License.
# All rights reserved.
#
# Changelog:
# 09/02/2004 - created
#

# $Platon: web-apps/fastcgi-gallery/_modules/Platon/FastCGI/Restart.pm,v 1.3 2005/09/08 23:34:02 rajo Exp $

package Platon::FastCGI::Restart;

use strict;
use Carp;
use English;
use File::stat;
use Digest::MD5;
use vars qw($VERSION $DEBUG $CLASS @EXPORT $AUTOLOAD);

$VERSION = sprintf("%d.%02d", q$Revision: 1.7 $ =~ /(\d+)\.(\d+)/);
$DEBUG   = 0 unless defined $DEBUG;

@EXPORT  = qw( add_files add_loaded_modules restart );

sub new
{ # {{{
    my ($this, $hash) = @_;
    my $self;
    
    if (ref $hash eq 'HASH') {
        #warn "Using HASH";
        $self  = {
            restart_func            => $hash->{restart_func},
            use_lock                => defined($hash->{use_lock})                ? $hash->{use_lock}                : 'true',
            lock_dir                => defined($hash->{lock_dir})                ? $hash->{lock_dir}                : '/var/tmp',
            max_restart_interval    => defined($hash->{max_restart_interval})    ? $hash->{max_restart_interval}    : 60,
            CHECK_USER_MODULES        => defined($hash->{CHECK_USER_MODULES})        ? $hash->{CHECK_USER_MODULES}    : 'true',
            CHECK_SYSTEM_MODULES    => defined($hash->{CHECK_SYSTEM_MODULES})    ? $hash->{CHECK_SYSTEM_MODULES}    : 'false',
            system_modules_regexp    => defined($hash->{system_modules_regexp})    ? $hash->{system_modules_regexp}: '^/usr',
        };
    }
    else {
        # Defaults:
        $self  = {
            restart_func            => &exit(0),
            use_lock                => 'true',
            lock_dir                => '/var/tmp',
            max_restart_interval    => 60,
            CHECK_USER_MODULES        => 'true',
            CHECK_SYSTEM_MODULES    => 'false',
            system_modules_regexp    => '^/usr',
        };
    }
    my $class = ref($this) || $this;
    $CLASS = $class;

    bless $self, $class;

    return $self;
} # }}}

sub add_files ($;@)
{ # {{{
    my ($self, @files) = @_;
    
    push @{$self->{checked_files}}, @files;

} # }}}

sub add_loaded_modules ($;)
{ # {{{
    my ($self) = shift;

    my @keys = sort keys %INC;
    #warn scalar(@keys) . " modules loaded";
    foreach my $file (@keys) {
        if ($INC{$file} =~ m#$self->{system_modules_regexp}#o) {
            if ($self->{CHECK_SYSTEM_MODULES} eq 'true') {
                #warn "Adding system module '$file'\t=>'$INC{$file}'\n";
                push @{$self->{checked_files}}, $INC{$file};
            }
        }
        elsif ($self->{CHECK_USER_MODULES} eq 'true') {
            #warn "Adding user module '$file'\t=>'$INC{$file}'\n";
            push @{$self->{checked_files}}, $INC{$file};
        }
    }
} # }}}

sub restart ($;@)
{ # {{{
    my ($self, @files) = @_;

    my @check_files = @{$self->{checked_files}};
    foreach my $file (@files) {
        push @check_files, $file if defined $file;
    }

    my $lock_file;
    if ($self->{use_lock} eq 'true') {
        $lock_file = "$self->{lock_dir}/fastcgi_restart-$EUID-" . Digest::MD5::md5_hex(join('', @files));
    }

    if (defined $self->{checked_files}) {
        foreach my $file (@check_files) {
            my $modif = -M $file;
            my $seconds = defined($modif) ? -86400.0 * $modif : 0.0;
            if (defined($seconds) and  $seconds > 0.0) {
                if (defined($lock_file)) { # use lockfiles
                    if (-f $lock_file) { # lock file exists
                        my $st = stat($lock_file);
                        my $lock_modif = time - $st->mtime();

                        if ($lock_modif < $self->{max_restart_interval}) {
                            carp "$CLASS: Max. restart interval is $self->{max_restart_interval}, lockfile created $lock_modif seconds ago. Restart delayled ...";
                            return;
                        }
                    }

                    # create lockfile
                    open FILE, ">$lock_file" or croak "Can't create lock file '$file': $!";
                    print FILE $PID; # write pid to this file
                    close FILE;
                }
                
                carp "$CLASS: File '$file' modified $seconds seconds after startup, restarting ...";
                &{$self->{restart_func}}; # call function, e.g. exit(0)
            }
        }
    }
    else {
        croak "$CLASS: Invalid module usage!";
    }
    
} # }}}

sub version ($;)
{ # {{{
    return $VERSION;
} # }}}

1;

__END__

=head1 NAME

restart - restart program (e.g. FastCGI script) if modules was moodified

=head1 SYNOPSIS

  use lib qw ( path/to/Platon/perl-modules );
  use Platon::FastCGI::Restart;

  $restart = Platon::FastCGI::Restart->new({
        restart_func          => sub { $req->LastCall(); exit 0 },
        use_lock              => 'true',
        lock_dir              => '/var/tmp',
        max_restart_interval  => 60,
        CHECK_USER_MODULES    => 'true',
        CHECK_SYSTEM_MODULES  => 'false',
  });
  
  $restart->add_loaded_modules();

  $restart->add_files(@filename_list);
  
  $restart->restart(@other_files);

=head1 EXAMPLE

  #!/usr/bin/perl -w
  
  use strict;
  use lib qw( ./modules path/to/Platon/perl-modules );

  use FCGI;
  use Platon::FastCGI::Restart;

  use vars qw (
      $req $restart
  );
  
  $req = FCGI::Request();
  $restart    = Platon::FastCGI::Restart->new({
          restart_func        => sub { $req->LastCall() ; exit 0; },
          CHECK_USER_MODULES    => 'true',
          CHECK_SYSTEM_MODULES    => 'false',
  });

  # All modules loaded, push them to the Platon::FastCGI::Restart:
  $restart->add_loaded_modules();

  my $runlimit = 1000;
  my $runcount = 0;
  while ( $runcount++ < $runlimit && ($req->Accept() >= 0) ) {

      # YOUR CODE HERE
    print "Content-type: text/html\r\n\r\n";
    
      $restart->restart($ENV{SCRIPT_FILENAME});
      $req->Finish();
  }

  1;

=head1 DESCRIPTION

The Platon::FastCGI::Restart module cleanly restart your FastCGI script
(or other program), when modules was modified.

=head1 AUTHORS

Lubomir Host 'rajo', <rajo AT platon.sk>

=head1 COPYRIGHT

Copyright (c) 2004 Platon SDG, http://platon.sk/
Licensed under terms of GNU General Public License.
All rights reserved.

=cut

# vim: ts=4
# vim600: fdm=marker fdl=0 fdc=3


Platon Group <platon@platon.sk> http://platon.sk/
Copyright © 2002-2006 Platon Group
Stránka používa redakčný systém Metafox
Na začiatok