类内使用Mac::FSEvents结合AnyEvent::io失效问题排查
封装到类中的AnyEvent+Mac::FSEvents无法触发文件变更事件
故障代码及现象
以下代码运行后,修改当前目录下的文件时无任何事件触发:
use strict; use warnings; use AnyEvent; use Data::Dumper; my $done = AnyEvent->condvar; my $watcher1 = AnyEvent::Filesys::Watcher::FSEvents->new; warn $watcher1->{__watchers}; $done->recv; package AnyEvent::Filesys::Watcher::FSEvents; use AnyEvent; use Mac::FSEvents; sub new { my ($class) = @_; my $self = {}; my $fs = Mac::FSEvents->new( latency => 0.1, file_events => 1, path => [ '.' ], ); my $fh = $fs->watch; my $watchers = [AnyEvent->io( fh => $fh, poll => 'r', cb => sub { warn "event fired"; exit 0; } )]; $self->{__watchers} = $watchers; bless $self, $class; }
第10行的调试输出已确认监听器变量未超出作用域(此类故障的常见原因)。
正常工作的对比代码
逻辑完全相同但未封装到类中的代码可正常运行,修改当前目录文件后会输出event fired:
use strict; use warnings; use AnyEvent; use Mac::FSEvents; use Data::Dumper; my $done = AnyEvent->condvar; my $fs = Mac::FSEvents->new( latency => 0.1, file_events => 1, path => [ '.' ], ); my $fh = $fs->watch; my $watcher2 = [AnyEvent->io( fh => $fh, poll => 'r', cb => sub { warn "event fired"; } )]; $done->recv;
环境信息与排查情况
- 运行环境:MacOS Sequoia (15.1)、Perl 5.40.0、Mac::FSEvents 0.22、AnyEvent 7.17
- 已尝试操作:
- 降级Mac::FSEvents至0.20、更换Perl 5.34.0/5.30.0版本,均无效果
- 使用标准输入替代文件句柄时,AnyEvent的IO监听可正常工作
- Linux系统下相同逻辑的测试可正常通过
- 推测原因:Mac::FSEvents、AnyEvent、Perl或macOS的更新导致组件间不兼容
背景补充
依赖Mac::FSEvents的AnyEvent::Filesys::Notify模块在当前系统上已失效,其测试用例t/30-event.t失败,表现与上述故障代码一致;自行编写的替代模块AnyEvent::Filesys::Watcher也存在相同问题。
内容的提问来源于stack exchange,提问作者Guido Flohr
相关产品推荐
相关产品推荐

