Yeah, in a sane world that would have fixed the problem, and in the importer codepath assumingly it did. But in the read message codepath... Well, the logic you put in made it so each time you created a Comment object, it added it to @unloaded_singletons (among other things). Then at some point preload_rows() gets called, which does this:
...(call absorb_row on unloaded_singletons, which sets $->{_loaded_row})
@unloaded_singletons = ();
so it gets all of the entries in @unloaded_singletons that don't have $_->{_loaded_row} set (which should be all of them--they're unloaded, right?), and, assuming that there are any unloaded singletons, loads those, and then clears out @unloaded_singletons.
But when reading comments on an Entry, you load those Comments in get_talk_data(), which does
my $make_comment_singleton = sub { my ($jtalkid, $row) = @_; return 1 unless $nodetype eq 'L';
# at this point we have data for this comment loaded in memory # -- instantiate an LJ::Comment object as a singleton and absorb # that data into the object my $comment = LJ::Comment->new($u, jtalkid => $jtalkid); # add important info to row $row->{nodetype} = $nodetype; $row->{nodeid} = $nodeid; $comment->absorb_row(%$row);
return 1; };
So it actually goes in and calls absorb_row() on each Comment, but, because it didn't go through preload_rows(), didn't remove the Comments from @unloaded_singletons. So here _all_ of the Comment objects in @unloaded_singletons have already had $_->{_loaded_row} set. Now that grep at the beginning of preload_rows() returns an empty array. So we return 1, @unloaded_singletons never gets cleared out, and next time we call preload_rows(), we go through all the Comment objects in @unloaded_singletons, none of them have $_->{_loaded_row} set...
Pretty terrible, huh? Maybe sophie should cover encapsulation next. :)
no subject
map { [ $_->journal, $_->jtalkid ] }
grep { ! $_->{_loaded_row} } @unloaded_singletons;
# already loaded?
return 1 unless @to_load;
...(call absorb_row on unloaded_singletons, which sets $->{_loaded_row})
@unloaded_singletons = ();
so it gets all of the entries in @unloaded_singletons that don't have $_->{_loaded_row} set (which should be all of them--they're unloaded, right?), and, assuming that there are any unloaded singletons, loads those, and then clears out @unloaded_singletons.
But when reading comments on an Entry, you load those Comments in get_talk_data(), which does
my $make_comment_singleton = sub {
my ($jtalkid, $row) = @_;
return 1 unless $nodetype eq 'L';
# at this point we have data for this comment loaded in memory
# -- instantiate an LJ::Comment object as a singleton and absorb
# that data into the object
my $comment = LJ::Comment->new($u, jtalkid => $jtalkid);
# add important info to row
$row->{nodetype} = $nodetype;
$row->{nodeid} = $nodeid;
$comment->absorb_row(%$row);
return 1;
};
So it actually goes in and calls absorb_row() on each Comment, but, because it didn't go through preload_rows(), didn't remove the Comments from @unloaded_singletons. So here _all_ of the Comment objects in @unloaded_singletons have already had $_->{_loaded_row} set. Now that grep at the beginning of preload_rows() returns an empty array. So we return 1, @unloaded_singletons never gets cleared out, and next time we call preload_rows(), we go through all the Comment objects in @unloaded_singletons, none of them have $_->{_loaded_row} set...
Pretty terrible, huh? Maybe