views:

92

answers:

2

In a fairly big legacy project, I've refactored several hairy modules into Moose classes. Each of these modules requires database access to (lazy) fetch its attributes. Since those objects are used pretty heavily, I want to reduce the number of redundant requests, for example for unchanged data.

Now, how do I do that properly? I've got several alternatives:

  1. Implement caching in my Moose classes via a role to store them in memcached with expiration of 5-10 minutes (probably not too difficult, but tricky with lazy attributes) update: KiokuDB could probably help here, have to read up about attributes
  2. Migrate to DBIx::Class (needs to be done anyway) and implement caching on this level (DBIC will probably take most of the pain away just by itself)
  3. Somehow make my objects persist inside the mod_perl process (no clue how to do this :()

How would you do this and what do you consider a sane way? Is caching data preferred on object or the ORM level?

A: 

Since you're already going to be doing DBIC anyway, it would make sense to let this change take care of it. It would make less sense to roll your own and then implement DBIC, giving your maintainers pause when they discover that you are using DBIC but with home-grown caching ..."for some reason."

The only reasons not to do this would be (1) if you really need that performance now and you don't have time to wait for the DBIC changes, since I imagine that'll be fairly extensive. Or (2), if you're not certain about whether you're really going to move to DBIC. If you haven't investigated it and you're doing a lot of custom SQL instead of basic CRUD, it might end up being a very small return on investment.

Adam Bellaire
+1  A: 

The short answer to #3 is: Don't use 'my'. You might do something like:

 use vars qw($object);
 # OR post perl5.6:
 # our ($object); 

 # create your object if it doesn't already exist
 $object ||= create_object;

 # Maybe reload some attributes if they have expired.
 $object->check_expires;

Objects created like this inside your handler will only be shared inside each Apache child, which is fine if you are reloading the data every 5-10 minutes. Any modules and objects that are read-only should be loaded in a PerlPostConfigRequire script so that they will be shared across all children.

stu42j