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

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

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

然后,我想也许我可以将词典放入缓存中,该缓存可能在需要时过期。但是,Locale :: Maketext中的%Lexicon哈希是在运行时开始时填充的,我无法弄清楚如何在每次请求时从缓存中填充它。

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

最佳答案

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

例如:

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磁盘高速缓存中,因此,尽管从磁盘上进行了所有明显的读取操作,但我希望它很快。

10-08 11:03