3

I have made my website multi-language via Locale::Maketext (or more specifically with CatalystX::I18N::Model::Maketext).

My maketext classes load the lexicon into the package var %Lexicon at compile time by loading it from a database.

I wanted to add an admin interface for the lexicon in my app, but I can't figure out a way to reload the lexicon. I added a method to each locale class to refresh the %Lexicon hash which worked fine in dev but when running on a forking server (Starman) it of course only reloads the package var in that server process.

I then thought perhaps I could put the lexicon in a cache, which could be expired when required. However, the %Lexicon hash in Locale::Maketext is populated at the start of runtime and I can't figure out how to populate it from cache at every request.

My latest thought was to override part of Locale::Maketext but I am looking for any smart ideas :)

cubabit
  • 2,527
  • 3
  • 21
  • 34

1 Answers1

0

If you are willing to undergo a slight performance hit for some requests you could check the md5sum of the file on each call to maketext().

For example:

package MyMakeText;

use strict;
use warnings;

use Digest::MD5;

my @PO_FILES = ('exaple.po');
my %FILE_TO_DIGEST;

my $LOCALIZER;

sub maketext {

    if (files_have_changed() || !$LOCALIZER) {
        $LOCALIZER = get_handle();
    }

    return $LOCALIZER->maketext(@_);
}

sub files_have_changed {
    my $files_have_changed = 0;

    for my $po_file (@PO_FILES) {
        open(my $fh, '<', $po_file) or die $!;
        my $md5sum = Digest::MD5->new->addfile($fh)->hexdigest;
        close($fh);

        if (!exists $FILE_TO_DIGEST{$po_file} || $FILE_TO_DIGEST{$po_file} ne $md5sum) {
            $FILE_TO_DIGEST{$po_file} = $md5sum;
            $files_have_changed = 1;
        }
    }

    return $files_have_changed;
}

Note this is partially pseudo-code as I don't know how you are currently constructing your Locale::MakeText object, so I've left it up to you to fill in get_handle(). But I think you can see how you can wrap your calls to maketext() to include a check to see whether any files have changed their contents.

.po files are usually very small, and recently changed files will usually be in the Linux disk cache, so I would expect this to be very fast despite all the apparent reads from disk.

Kaoru
  • 1,540
  • 11
  • 14