On Mon, 2 Dec 2002, Tim Sweetman wrote:

> 1. Its temporary filename doesn't incorporate anything random, or the
> process ID. So should you happen to have two processes running
> simultaneously (eg. wraparound cron syndrome), you could end up end with
> interleaved interleaved content and not be very content content. Innit.

Yes, this is true.  Don't do that.  Or use some external locking method.
;-)

Currently IO::AtomicFile is one step up from the basic IO::File.  It is
what it is.

Actually I was thinking of writing some patches to IO::AtomicFile to turn
on the options of

 a) Optionally locating the temp file in another dir on the same
    filesystem

 b) Allowing random filenames as temp files, thus avoiding the need to
    lock

I've already done some work on this, but then I got really busy writing
the actual calendar.  As I said on IRC just now, I'll do more on it after
the 25th.  The actual patches aren't hard, it's writing the interface,
getting the documentation and tests together that are causing the
problems.

> If you don't explicitly do the "disaster recovery" bit by using an eval
> block and the ->delete method .... Admittedly this makes life easier for
> people .... who don't want to write "->commit", but that strikes me as
> the Wrong design decision.

I like the way it works.  It doesn't get in the way when I'm working, I
just use it as normal.  When something goes wrong - when there's
an Exception, this is the exceptional case.  I like having separate error
handling code.  Most of my code looks like this

 my $fh = IO::AtomicFile->new("foo",">")
    or die "Can't open 'foo': $!";

 eval
 {
   print {$fh} $self->bar();
   print {$fh} $self->baz();
   print {$fh} $self->buzz();
   close $fh;
 };

 if ($@)
 {
   $fh->delete;
   ... other error handling code ...
 }

(obviously bar, baz and buzz throw exceptions if there's any problems)

What you're suggesting is something like

 my $fh = IO::AtomicFile->new("foo",">")
    or die "Can't open 'foo': $!";

 eval
 {
   print {$fh} $self->bar();
   print {$fh} $self->baz();
   print {$fh} $self->buzz();
   $fh->commit;
   close $fh;
 };

 if ($@)
 {
   ... other error handling code ...
 }

I can see how that would work.  If I was the author I'd probably either
put it as an option in the constructor, or write a subclass
IO::AtomicFile::Explict that only moved when you called commit.

Maybe you should email the author ([EMAIL PROTECTED]) with these
suggestions, or one of us could whap them into rt.

Later.

Mark.

--
  Mark Fowler
  http://www.twoshortplanks.com/          The 2002 Perl Advent Calendar
  [EMAIL PROTECTED]               http://www.perladvent.org/2002/
                             a different perl module featured every day


Reply via email to