In my last installment I found out that destruction of objects durning global garbage collection happens in a somewhat random order.
So, I need to make sure that all of my code undefines the $session instead of letting Perl do it for me. This way I know that the objects I'm referring haven't been destroyed yet and I can clean up properly.
Since this code runs in a Mason environment, the natural thing to do was insert a cleanup section in my autohandlers. But, I wasn't sure I had got them all.
And, I wanted to make sure that if I created an autohandler in the future that I remembered to clean my session.
Since I'm working on tests for the application, this seemed like a natural fit. So, I wrote a test to check all of my autohandlers for the correct code.
Now, if I create another autohandler it will get caught by the test script. At the very worst I'll have to update the plan. But, I won't forget to clean my session!
--- the code ---
#!/usr/bin/perl
# check all of the autohandlers and dhandlers and make sure that they have a cleanup section # that undefines the $session variable if they do not inherit from another file
use strict; use warnings;
use Test::More tests => 20;
# start in this directory my $app_dir = '/home/Mason/comp/Gradebook/';
use File::Find::Rule;
my $rule = File::Find::Rule->new; $rule->or( $rule->new->directory->name('CVS')->prune->discard, $rule->new->directory->name('Admin')->prune->discard, $rule->new->file->name('autohandler'), $rule->new->file->name('dhandler') ); my @files = $rule->in($app_dir);
foreach my $handler (@files) { # open our file and read it in open I, $handler or print 'Bail out!'; local $/; my $code = ; close I;
# first we need to check and see if this autohandler inherits from another if ($code =~ m|^<%flags>\ninherit=>'undef'\n%flags>|sm){ # if it doesn't then it should have a cleanup section # let's grab the contents $code =~ m|^<%cleanup>(.*)%cleanup>|sm; my $cleanup = $1 || ''; # so we don't trigger a warning with undefined scalar # and check to see that we are triggering the DESTROY method of our session ok( $cleanup =~ m|undef \$session;$|sm , "$handler cleans the session" ); } # if inherits } # foreach handler
Re:Not a good idea
phillup on 2004-11-13T19:09:23
Yeah, this was one of those 80% solutions.
I started with the custom handler but it wasn't playing nicely with some of my internal redirects. So, this was kind of a "quick hack" 'till I could study the problem a bit more.
The flip side of the coin is that I never had a problem in the Mason environment with the session and just letting it get destroyed during global destruction. I did, however, notice the problem when I needed to make a change to the database and decided to use the session module to do most of the work... because it already had methods in it to do what I needed.
It was while writing a script to run from the command line that I noticed the problem with the session.