Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I implement an atomic sequence in Perl?

I have the following requirements:

  1. The sequence is unique to a host (no shared incrementing is necessary)
  2. The sequence must be monotonically increasing.
  3. The sequence must be persistent across processes.
  4. Incrementing the sequence must be atomic in the case of multiple processes working on it at the same time.
  5. Most of the time the file will be updated and the new value read after update. But, it should also be possible to read the current value without update.

I can hack together perl code that will do roughly this, but I'd like a more elegant solution.

like image 301
Chris R Avatar asked Jun 09 '11 19:06

Chris R


1 Answers

Store the sequence number in a file and use flock to make sure only one process can access it:

sub set {     # seed the sequence number file
    my ($file, $number) = @_;
    open my $fh, '>', $file;
    print $fh $number;
}  # implicit close

sub get {
    my $file = shift;
    my $incr = @_ ? shift : 1;   # get($f) is like get($f,1)
    open my $lock, '>>', "$file.lock";
    flock $lock, 2;
    open my $fh, '<', $file;
    my $seq = <$fh>;
    close $fh;
    set($file, $seq+$incr) if $incr;   # update sequence number
    close $lock;
    return $seq;
}

You can call this as get($file,0) to retrieve the sequence number without changing it.

like image 104
mob Avatar answered Sep 27 '22 22:09

mob