[Catalyst] Chained actions usage and DBIC performance

Nilson Santos Figueiredo Junior acid06 at gmail.com
Mon Oct 30 18:02:27 GMT 2006


Lately I've been using chained actions a lot, since it ends up making
everything look cleaner and more organized.

I tend to structure things in a way that I've got some Catalyst
actions that load some items from the database   which are the root of
the chain and then I've got another set of Catalyst actions that
actually do things with those loaded items (e.g. /item/12/view,
/item/12/edit, and so on).

Sometimes, those items also have subitems and those might even have
another set of subitems. In these cases, when using Catalyst and
DBIx::Class it can be useful to prefetch stuff for performance
reasons. But, using my setup it's not currently possible to do that,
so I end up issuing lots of queries to the database since the initial
root item didn't prefetch anything, because it couldn't know in
advance what would be needed by the chained actions.

Most of the item loading code I've previously mentioned looks like
this (simplified):

  sub load : Chained('/item') PathPart('') CaptureArgs(1) {
    my ($self, $c, $id) = @_;
    $c->stash->{item} = $c->model('DB')->find($id);
  }

The only work around I could think of is to prefetch everything and
hope that it would result in a performance gain, at least on average.
But, honestly, I find it a kind of crappy solution so I didn't even
implement it.

I'd like to know how people usually handle this because there must a
better way than ignoring performance concerns at all.

The only better way I could think of would be if DBIC's ->find()
worked in a similar way to ->search() and only actually fetched the
values when they were needed. So I could add prefetch conditions
arbitrarily using stacked find() calls. Maybe this should be suggested
on DBIC mailing list? Or am I just complicating a trivial situation
and there's a simple way around this problem?

-Nilson Santos F. Jr.



More information about the Catalyst mailing list