可能是一个很长的镜头,但我想知道是否有人以前见过这样的错误,因为我无法在生产环境之外重现它。基本上情况如下:
- 我有一个名为
My::Budget::Module
(为简单起见重命名)的模块,它负责更新应用程序中给定对象的“预算” My::Budget::Module
使用我构建的一个对象Moo
,My::Bulk::Update::Module
它执行以下操作:- 构建需要更新的数据库行数组
- 构建一个 MySQL 更新查询字符串/语句,它将一次更新所有行
- 实际上一次更新所有行
- 然后
My::Bulk::Update::Module
将执行更新并将已更新的行标记为“陈旧”,以便它们不会被缓存
在添加要更新的行之后但在实际应用更新的代码返回之前,错误似乎总是发生在某处。
如果您查看我在下面包含的堆栈跟踪,您会看到错误采用以下形式
Attempt to bless into a reference at...
并且发生这种情况的点是在 from 的构造函数中Moo/Object.pm
(Version 2.003002
请Moo
参见cpan
此处)。
Attempt to bless into a reference at /path/to/module/from/cpan/Moo/Object.pm line 25 at /path/to/module/from/cpan/Moo/Object.pm line 25.
Moo::Object::new(My::Bulk::Update::Module=HASH(0xf784b50)) called at (eval 1808) line 28
MongoDB::Collection::new(My::Bulk::Update::Module=HASH(0xf784b50)) called at /path/to/my/bulk/update/module line XXXX
My::Bulk::Update::Module::apply_bulk_update(My::Bulk::Update::Module=HASH(0xf784b50)) called at /path/to/my/budget/module line XXXX
My::Budget::Module::update_budget(My::Budget::Module=HASH(0xf699a38)) called at /path/to/my/budget/module line XXXX
向后移动堆栈跟踪会导致MongoDB::Collection
&这就是事情开始变得非常奇怪的地方。
MongoDB::Collection
也是一个模块,但此时出现的模块会有所不同,除了它始终是一个对象cpan
外,我在这里看不到模式。Moo
此外,我不确定为什么要实例化这个模块,因为MongoDB::Collection::new
在提到的那一行没有调用。
此外,从堆栈跟踪来看,它看起来像MongoDB::Collection
并被Moo::Object
实例化,第一个参数是My::Bulk::Update::Module=HASH(0xf784b50)
. 鉴于应用程序逻辑,我认为不MongoDB::Collection
应该在这里实例化也不应该My::Bulk::Update::Module
传递给它MongoDB::Collection
。
除了它是一个Moo
对象之外,My::Bulk::Update::Module
它不扩展任何其他模块,并且被设计为一个独立的“实用程序”模块。它仅在整个应用程序中的一处使用。
有没有人见过类似的东西?
编辑:添加更多代码 -apply_bulk_update
根本没有做太多。这里没有调用MongoDB::Collection
,MongoDB::Collection
只是“碰巧”成为这个特定示例中堆栈跟踪中包含的模块。这并不总是MongoDB::Collection
- 我也见过MongoDB::Timestamp
,,,MongoDB::Cursor
等Search::Elasticsearch::Serializer::JSON
Search::Elasticsearch::Logger::LogAny
sub apply_bulk_update
{
my $self = shift;
my ($db) = @_; # wrapper around DBI module
my $query = $self->_generate_query(); # string UPDATE table SET...
my $params = $self->_params; # arrayref
return undef unless $params && scalar @$params;
$db->do($query, undef, @$params);
}
代码有时apply_bulk_update
一被调用就死掉,有时在调用时死掉,有时_generate_query
在查询在最后一行执行之后......