There was DEFINETLY a race condition, I used a technique similar to this:

http://www.stonehenge.com/merlyn/WebTechniques/col54.html

to solve the problem. There were so many instances where either the live or
the temp file would have been overwritten, it wasn't even, well funny.


for the curious, this is what the subroutine looks like now, there's way too
many file openings for my liking, but it's built for comfort, not good looks
:) 


<snip> 

sub remove_from_list {

my %args = ( 
-List       => undef,
-Path       => $lists,
-Email_List => undef,
-Type       => 'list',
@_,
); 

my $list = $args{-List};
my $path = $args{-Path};
my $type = $args{-Type};
my $deep_six = $args{-Email_List};


if($list and $deep_six){


    # create the lookup table
    my %lookup_table;
    foreach my $going(@$deep_six){
        chomp($going);
        $going = strip($going);
        $lookup_table{$going} = 1;
    }


    # the lookup table holds addresses WE DON'T WANT. SO rememeber that, u
    my $main_list = "$path/$list.$type";
    
    my ($sec, $min, $hour, $day, $month, $year) = (localtime)[0,1,2,3,4,5];
    my $message_id = sprintf("%02d%02d%02d%02d%02d%02d", $year+1900,
$month+1, $day,  $hour, $min, $sec);
    
    my $temp_list = "$main_list.tmp-$message_id";
    my $count; 


########################################################################
# this is my big hulking Masterlock that you'll need a shotgun
# to blow off. This is me being anal retentive.
#
#
#
#



sysopen(SAFETYLOCK, "$lists/$list.lock",  O_RDWR|O_CREAT, $file_chmod)
    or die "Mojo Mail $ver Error - Cannot open list lock file
'$lists/$list.lock' - $!";

    {
    
    my $sleep_count = 0;
        { 
        flock SAFETYLOCK, LOCK_EX | LOCK_NB and last;
        sleep 1;
        redo if ++$sleep_count < 11;
        
        # ok, we've waited 'bout 10 seconds...
        # nothing's happening, let's say  fuck it.
        
        warn "Mojo Mail $ver Warning: Server is way too busy to unsubscribe
people, waited 10 seconds to get access to the list file for $list, giving
up: $!\n";
    
        return 'too busy';
        exit(0); 
    }
}


        
#
#
#
# safety lock is set. This should give us a nice big shield to do some file
# juggling and updating. I think there is a race condition between when the
# the first time the temp and list file are open, and the second time.
# This should stop that. wee.
############################################################################
        



    #open the original list
    sysopen(MAIN_LIST, $main_list,  O_RDONLY|O_CREAT, $file_chmod) or
        die "Mojo Mail $ver Error: Can't open email list to sort through and
make deletions at '$main_list': $!";
    flock(MAIN_LIST, LOCK_SH) or
        die "Mojo Mail $ver Error: Can't create a exclusive lock to sort
through and make deletions at '$main_list': $!";
  
    # open a temporary list
    sysopen(TEMP_LIST, $temp_list,  O_RDWR|O_CREAT, $file_chmod) or
        die "Mojo Mail $ver Error: can't create temporary list to sort out
deleted e-mails at '$temp_list': $!" ;
    flock(TEMP_LIST, LOCK_EX) or
        die "Mojo Mail $ver Error: can't create an exculsive lock to sort
out deleted e-mails at'$temp_list': $!" ;
        
    my $check_this;

    while(defined($check_this  = <MAIN_LIST>)){
         #lets see, if they pass, send em over.
         chomp($check_this);
         $check_this = strip($check_this);
         
         # unless its in out delete list,
          unless(exists($lookup_table{$check_this})){
              # print it into the temporary list
              print TEMP_LIST $check_this, "\n";

          }else{
              #missed the boat!
              $count++;
              
              # js - log it
                $log->mj_log($args{-List},'Unsubscribed from $list.$type',
$check_this) if $LOG{subscriptions};
          }

    }


    close (MAIN_LIST) or
        die "Mojo Mal $ver Error - did not successfully close file
'$main_list': $!"; 
        
    close (TEMP_LIST) or
        die "Mojo Mal $ver Error - did not successfully close file
'$temp_list': $!";

#open the new list, open the old list, copy old to new, done.


    sysopen(TEMP_LIST, $temp_list,  O_RDONLY|O_CREAT, $file_chmod) or
        die "Mojo Mail $ver Error: Can't open temp email list '$temp_list'
to copy over to the main list : $!";
    flock(TEMP_LIST, LOCK_SH) or
        die "Mojo Mail $ver Error: Can't create a exclusive lock to copy
over email addresses at  '$temp_list': $!";


    sysopen(MAIN_LIST, $main_list,  O_WRONLY|O_TRUNC|O_CREAT, $file_chmod)
or 
        die "Mojo Mail $ver Error: can't open email list to update
'$main_list': $!" ;
    flock(MAIN_LIST, LOCK_EX) or
        die "Mojo Mail $ver Error: can't create an exclusive lock to update
'$main_list': $!" ;
        
        
    my $passed_email;
    while(defined($passed_email  = <TEMP_LIST>)){
         #lets see, if they pass, send em over.
         chomp($passed_email);
         print MAIN_LIST $passed_email, "\n";
    }
    
        close (MAIN_LIST) or
        die "Mojo Mal $ver Error - did not sucessfully close file
'$main_list': $!"; 
        
        close (TEMP_LIST) or
        die "Mojo Mal $ver Error - did not sucessfully close file
'$temp_list': $!";
        
        unlink($temp_list) or
        warn "Mojo Mail  $ver Error: Could not delete temp list file
'$temp_list': $!"; 

        
    

        
close(SAFETYLOCK); 
return $count; 
    
    

}else{ 

warn('Mojo Mail Error: No list information given at GUTS.pm for
remove_from_list()');

return ('no list');
}
              
}

</snip> 

THAT subroutine replaced this:

<snip> 

sub remove_from_list {

my %args = ( 
-List       => undef,
-Path       => $lists,
-Email_List => undef,
-Type       => 'list',
@_,
); 

my $list = $args{-List};
my $path = $args{-Path};
my $type = $args{-Type};
my $deep_six = $args{-Email_List};


if($list and $deep_six){
#print "Content-type: text/html\n\n";

# create the lookup table
my %lookup_table; 
foreach(@$deep_six){$lookup_table{$_} = 1}
# the lookp table holds addresses WE DON'T WANT. SO rememeber that, u


my $old = "$path/$list.$type";
my $new = "$old.tmp";

my $count; 

sysopen(OLD_LIST, $old,  O_RDONLY|O_CREAT, $file_chmod) or
    warn "Mojo Mail Error: Can't open email list to sort through and make
deletions at '$old': $!";
sysopen(NEW_LIST, $new,  O_RDWR|O_CREAT, $file_chmod) or
    warn "Mojo Mail Error: can't open temporary list to sort out deleted
e-mails at '$new': $!" ;
my $check_this; 


while(defined($check_this  = <OLD_LIST>)){
     #lets see, if they pass, send em over.
     chomp($check_this);
      unless(exists($lookup_table{$check_this})){
          print NEW_LIST $check_this, "\n";
           
      }else{
      #missed the boat!
      $count++;
      }

}


close (OLD_LIST); 
close (NEW_LIST); 

unlink($old) or 
    die "Mojo Mail Error: Could not delete old list file to be replaced with
new list file at $old: $!";
rename($new, $old) or
    die "Mojo Mail Error: Could not rename new list file to make it current
at $new: $!";      

return $count; 

}else{ 

warn('Mojo Mail Error: No list information given at GUTS.pm for
remove_from_list()');
return 0;
}
              
}

</snip> 



flat files are fun, aren't they? :) I haven't had any problems since making
this change, i was losing sleep before.


-- 

justin simoni 

personal musings ~  http://skazat.com
____________________________________________________
The only possible ETHIC is to do what one wants to do.
                                                          w. burroughs








-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to