3

我通过Locale::Maketext(或更具体地说,使用CatalystX::I18N::Model::Maketext)使我的网站成为多语言。

我的 maketext 类在编译时通过从数据库加载词典将词典加载到包 var %Lexicon 中。

我想在我的应用程序中为词典添加一个管理界面,但我想不出一种重新加载词典的方法。我向每个语言环境类添加了一个方法来刷新 %Lexicon 哈希,这在 dev 中运行良好,但是当在分叉服务器(Starman)上运行时,它当然只会在该服务器进程中重新加载包 var。

然后我想也许我可以把词典放在一个缓存中,在需要时它可能会过期。但是,Locale::Maketext 中的 %Lexicon 哈希是在运行时开始时填充的,我不知道如何在每次请求时从缓存中填充它。

我最新的想法是覆盖 Locale::Maketext 的一部分,但我正在寻找任何聪明的想法:)

4

1 回答 1

0

如果您愿意对某些请求造成轻微的性能影响,您可以在每次调用时检查文件的 md5sum maketext()

例如:

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;
}

请注意,这部分是伪代码,因为我不知道您当前是如何构造 Locale::MakeText 对象的,所以我留给您填写get_handle(). 但我认为您可以看到如何包装您的调用以maketext()包括检查是否有任何文件更改了其内容。

.po文件通常非常小,最近更改的文件通常会在 Linux 磁盘缓存中,所以我希望这会非常快,尽管所有明显的磁盘读取。

于 2014-06-05T21:44:59.103 回答