Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

How to use Storable in CGI scripts

by kingman (Scribe)
on Nov 29, 2002 at 18:39 UTC ( [id://216574]=perlquestion: print w/replies, xml ) Need Help??

kingman has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm using Storable as a kind of mini DB for a CGI script. Everythings works fine but I'm wondering if what I'm doing is safe (in terms of data corruption) if the script gets a lot of concurrent hits. Is it ok to use Storable in this way? I'm saving a complex data structure but the following simplied example shows what I'm trying to do.
#!/usr/bin/perl use strict; use warnings; use Storable qw/lock_store lock_retrieve/; use CGI; use Thread::Semaphore; my $q = new CGI; my $s = new Thread::Semaphore; $s->up; my $x = lock_retrieve('k.dat') or die "Can't open k.dat: $!"; $x->{counter}++; $x = lock_store('k.dat') or die "Can't save k.dat: $!"; $s->down; print $q->header; print "<h1>Hi</h1>\n";
Thanks!

Replies are listed 'Best First'.
Re: How to use Storable in CGI scripts
by chromatic (Archbishop) on Nov 29, 2002 at 19:11 UTC

    That offers no protection in a standard CGI environment. If you had multiple threads within this program it would be useful. In this case, there are multiple processes which could be accessing your file simultaneously. You'll need a filesystem-level mechanism to manage file locking. There are plenty of nodes that describe how to use flock appropriately.

      I found an article on this at The Perl Journal. Here's my second version:
      #!/usr/bin/perl use strict; use warnings; use Sem; use Storable qw/lock_store lock_retrieve/; use CGI; my $q = new CGI; my $sem = Sem->new('semaphore.txt'); my $x = lock_retrieve('k.dat') or die "Can't open k.dat: $!"; $x->{counter}++; lock_store($x, 'k.dat') or die "Can't save k.dat: $!"; $sem->unlock; print $q->header;
      And here's the Sem.pm code:
      package Sem; sub new { my $class = shift(@_); use Carp (); my $filespec = shift(@_) || Carp::croak("What filespec?"); open my $fh, ">", $filespec or Carp::croak("Can't open semaphore f +ile $filespec: $!"); chmod 0666, $filespec; # assuming you want it a+rw use Fcntl 'LOCK_EX'; flock $fh, LOCK_EX; return bless {'fh' => $fh}, ref($class) || $class; } sub unlock { close(delete $_[0]{'fh'} or return 0); return 1; } 1;
      Is there anyway to test this? Should I use the apache benchmark tool to send a bunch of concurrent requests to the cgi?
      Hi, Thanks for your response. What happens when a user runs the cgi and the file is flocked? Does Apache queue them or does the script die?

        It's up to you. You can have the program wait to retrieve a lock, or you can cause it to die.

Re: How to use Storable in CGI scripts
by iguanodon (Priest) on Nov 30, 2002 at 14:02 UTC
    Check out Apache::Session. You can use a flat file (or a database if you prefer) and it will take care of the file locking details for you.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://216574]
Approved by chromatic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (7)
As of 2024-04-23 20:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found