Util::ShortTermRepository (version 0.0)


package Util::ShortTermRepository;
##############################################################################
#
# DESCRIPTION: 
#
# HISTORY:
#
# VERSION: 0.0
#
##############################################################################

use strict;

#########################
# constructor
#########################
sub new { #(directory)
    my $proto = shift;
    my $class = ref($proto) || $proto;

    #####################################
    # initialize some variables
    #####################################
    my $self={};
    $self->{DIR}=shift;
    $self->{FILENAME}=shift;
    $self->{FILES}={};
    $self->{LOCK_TIMEOUT}=60*10; # ten minutes

    bless($self,$class);
    return $self;

} # end of constructor

#########################
# accessors
#########################

##############################################################################
#
##############################################################################
sub log {
    my $self = shift;
    return $self->{FILENAME}->log();
}

#########################
# methods
#########################

##############################################################################
#
##############################################################################
sub lock {
    my $self = shift;
    my $type = shift;

    my $log = $self->log();

    ##################################
    # construct the directory name
    ##################################
    my $dir = "$self->{DIR}/$type";

    my $lock = "$dir.lock";

    ##############################################
    # tell the log if we have to wait for a lock
    ##############################################
    if( -f $lock ) {
        $self->log()->entry("Waiting for lock on repository dir $dir");
    }

    ###################################
    # wait for the lock to be released
    ###################################
    my $time0 = time();
    while( -f $lock  ) {

        if(time() - $time0 > $self->{LOCK_TIMEOUT}) {
            #########################################
            # we can sit around here waiting forever
            #########################################
            $log->error(1, "Repositiry lock $lock expired ".
                           "after $self->{LOCK_TIMEOUT} seconds");
            $self->unlock($dir);
            last;
        }

        sleep 10;
    } # end of lock wait loop

    ############################
    # create a new lock
    ############################
    system("touch $lock");

    #################################
    # make sure the directory exists
    #################################
    if ( ! -d $dir ) {
        system("mkdir $dir");
    }

    return $dir;

} # end of lock method

##############################################################################
#
##############################################################################
sub unlock {
    my $self = shift;
    my $dir = shift;

    unlink "$dir.lock";

} # end of unlock method


##############################################################################
#
##############################################################################
sub export {
    my $self = shift;
    my $type = shift;

    my $dir = $self->lock($type);

    my @files = @_;
    unless(@files) {
        #########################################
        # export all the files of the given type
        #########################################
        @files = $self->{FILENAME}->any($type);
    }

    ########################################
    # copy all the files to the repository
    ########################################
    my $file;
    foreach $file (@files) {

        system("cp $file $self->{DIR}/$type");
    }

    $self->unlock($dir);


} # end of export method

##############################################################################
#
##############################################################################
sub fetch {
    my $self = shift;
    my $type = shift;
    my @args = @_;

    my $filename = $self->{FILENAME};

    ########################
    # lock the repository
    ########################
    my $dir = $self->lock($type);

    ##############################################
    # locate the file in the repository directory
    ##############################################
    $filename->glob_dir($dir);
    my $file = $filename->get($type, @args);

    ################################################################
    # if we located the file, copy it into the working directory
    ################################################################
    if($file && $self->{FILENAME}->fetch($file, $dir) ) {
        ###########################################################
        # we got a file, so remember its name for cataloging later
        ###########################################################
        $self->remember($type, $file);
    }


    $self->unlock($dir);
    return $file;
    
} # end of fetch method


##############################################################################
# store a file name and type internally so that it can be included in a catalog
# of all fetched files later.
##############################################################################
sub remember {
    my $self = shift;
    my $type = shift;
    my $file = shift;

    unless($self->{FILES}->{$type}) {
        $self->{FILES}->{$type} = {};
    }

    $self->{FILES}->{$type}->{$file} =1;

} # end of remember method


1;