如何在Mojolicious应用中定时更新模型哈希内容?
在Mojolicious中实现定时更新模型的方法
完全可以,Mojolicious依托自身的事件循环就能实现定时调度任务,不用额外依赖第三方模块。下面给你调整代码,实现定期自动更新用户哈希的功能:
优化思路
- 把用户哈希做成全局缓存,避免每次请求都重复读取解析CSV,提升性能
- 用Mojo::IOLoop的
recurring方法设置定时任务,按指定间隔自动执行更新 - 替换CSV解析逻辑为专业模块
Text::CSV,解决split(',')无法处理带引号、含逗号字段的问题
修改后的完整代码
use Mojolicious::Lite -signatures; use Mojo::Date; use Mojo::File; use Text::CSV; # 需提前安装:执行 cpanm Text::CSV # 全局缓存:存储解析后的用户哈希 my $users_cache = {}; # 加载CSV数据到缓存的通用函数 sub load_users_to_cache { my $newest; # 找出最新的CSV文件 foreach my $filename (sort {$b cmp $a} glob("1*.csv")) { $newest = $filename; last; } return unless $newest; my $csv = Text::CSV->new({binary => 1, auto_diag => 1}) or die Text::CSV->error_diag; open my $fh, "<:encoding(utf8)", $newest or die $!; $csv->getline($fh); # 跳过表头行 $users_cache = {}; while (my $row = $csv->getline($fh)) { my ($name, $email, $phone) = @$row; $users_cache->{$email} = $name if $email; } close $fh; } # 应用启动时初始化缓存 load_users_to_cache(); # 定时任务:每30分钟执行一次更新(1800秒) # 测试时可改为60秒(每分钟一次),生产环境按需调整 Mojo::IOLoop->recurring(1800 => sub ($loop) { app->log->info("开始执行定时更新用户数据..."); my $result = app->update; if ($result eq 'ok') { load_users_to_cache(); app->log->info("用户数据更新完成"); } else { app->log->error("更新失败: $result"); } }); helper users => sub($self) { # 直接返回缓存,无需重复解析文件 return $users_cache; }; helper update => sub ($self) { my $tx = $self->ua->get('https://test-backend.lambdatest.com/api/dev-tools/csv-generator'); my $res = eval { $tx->result }; return $@ if $@; return "请求失败: " . $tx->error->{message} unless $res->is_success; my $epoch = Mojo::Date->new()->epoch; Mojo::File->new("${epoch}.csv")->spurt($res->text); return 'ok'; }; get '/' => sub ($self) { my @names = sort values %{ $self->users }; $self->render(json => {emails => [@names]}); }; get '/update' => sub ($self) { my $result = $self->update; if ($result eq 'ok') { load_users_to_cache(); $self->render(text => '手动更新完成'); } else { $self->render(text => "更新失败: $result", status => 500); } }; app->start;
关键说明
- 全局缓存:
$users_cache存储解析后的用户数据,所有请求直接复用,大幅减少磁盘IO操作 - 定时任务:
Mojo::IOLoop->recurring是Mojolicious原生定时API,第一个参数为间隔秒数,第二个是要执行的回调函数 - 日志记录:定时任务中加入日志输出,方便排查更新状态
- 手动更新兼容:保留原有的
/update路由,支持手动触发更新
内容的提问来源于stack exchange,提问作者h q
相关产品推荐
相关产品推荐

