Good Morning Octavian
On 10/30/2009 12:12 AM, Octavian Râşniţă wrote:
I've seen that by just adding the attribute "FormConfig" in a subroutine
declaration in a Catalyst controller that subclasses
Catalyst::Controller::HTML::FormFu decreases the response speed from 36
requests to only 5 requests per second, without changing anything else.
I had a similar experience which was making FormFu impractical.
Is it possible to cache somehow the config files or do something else to
improve the speed?
I've implemented a simple (naive) single-process cache in
Catalyst::Controller::HTM::FormFu::Action::FormConfig
(file attached) and get a noticeable speed up, however, there are issues
with this approach. As you can see from the comments in the code, I was
unable to get a shared cache to work, and caching code references seems
to be impossible. I'm also thinking of applying this
approach to (applicable instances of) FormMethod as well.
Cheers!
Kal
--
Kahlil (Kal) Hodgson GPG: C37B01F4
Head of Technology (m) +61 (0) 4 2573 0382
DealMax Pty Ltd (w) +61 (0) 3 9008 5281
Suite 1005
401 Docklands Drive
Docklands VIC 3008 Australia
"All parts should go together without forcing. You must remember that
the parts you are reassembling were disassembled by you. Therefore,
if you can't get them together again, there must be a reason. By all
means, do not use a hammer." -- IBM maintenance manual, 1925
package Catalyst::Controller::HTML::FormFu::Action::FormConfig;
use strict;
use warnings;
use base qw( Catalyst::Action Class::Data::Inheritable );
use Config::Any;
use NEXT;
use Scalar::Util qw/ weaken /;
# add caching which speeds up the second form load by a factor of 2-3
my %form_cache =();
# need this for safe retrieval of cached CODE refs
#my $Safe = Safe->new();
#$Safe->permit(qw(:default require));
# add caching which speeds up subsequent form loads by a factor of 2-3
#use Cache::FastMmap;
#my $FormCache = Cache::FastMmap->new(init_file => 1);
sub execute {
my $self = shift;
my ( $controller, $c ) = @_;
my $config = $controller->_html_formfu_config;
return $self->NEXT::execute(@_)
unless exists $self->attributes->{ActionClass}
&& $self->attributes->{ActionClass}[0] eq $config->{config_action};
my $form = $controller->_form;
my @files = grep {length} split /\s+/, $self->{_attr_params}->[0] || '';
if ( !...@files ) {
push @files, $self->reverse;
}
my $ext_regex = $config->{_file_ext_regex};
my $context_stash = $config->{context_stash};
for my $file (@files) {
# $c->log->debug( __PACKAGE__ ." loading config file '$file'" )
# if $c->debug;
# preserve CODE references (does not work)
#local $Storable::Deparse = 1;
#local $Storable::Eval = 1;
#local $Storable::Eval = sub { $Safe->reval($_[0]) };
#my $cached_form = $FormCache->get($file);
my $cached_form = $form_cache{$file};
if ($cached_form) {
# $c->log->debug(
# __PACKAGE__ ." loading config file '$file' from cache"
# ) if $c->debug;
$form = $cached_form->clone();
# reinsert the bits we lost with the clone
# basically $controller->_common_construction($form);
# but just the bits we want
$form->query( $c->request );
$form->stash->{$context_stash} = $c;
weaken( $form->stash->{$context_stash} );
}
else {
if ( $file =~ m/ \. $ext_regex \z /x ) {
$form->load_config_file( $file );
}
else {
$form->load_config_filestem( $file );
}
# any attempt at storing CODE ref is going fail
eval {
my $form_clone = $form->clone();
#FIXME clonning does not disentangle the context referenced
# by the form object, so we cant delete it even though it
# gets overwritten when we pull it out of the cache.
#$form_clone->stash->{$context_stash} = undef;
$form_cache{$file} = $form_clone;
#$FormCache->set($file, $form_clone);
};
}
}
$form->process;
$c->stash->{ $config->{form_stash} } = $form;
$self->NEXT::execute(@_);
}
1;
_______________________________________________
HTML-FormFu mailing list
HTML-FormFu@lists.scsys.co.uk
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/html-formfu