[dw-free] http://bugs.dwscoalition.org/show_bug.cgi?id=3641
[commit: http://hg.dwscoalition.org/dw-free/rev/40cdb938430c]
http://bugs.dwscoalition.org/show_bug.cgi?id=3641
Better caching, and short-circuit when we hit something in the cache.
Patch by
fu.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=3641
Better caching, and short-circuit when we hit something in the cache.
Patch by
Files modified:
- cgi-bin/LJ/Comment.pm
- cgi-bin/LJ/S2.pm
- htdocs/talkread.bml
- t/subscription-nested.t
--------------------------------------------------------------------------------
diff -r 116559a9f5bb -r 40cdb938430c cgi-bin/LJ/Comment.pm
--- a/cgi-bin/LJ/Comment.pm Tue May 17 10:20:10 2011 +0800
+++ b/cgi-bin/LJ/Comment.pm Tue May 17 10:38:49 2011 +0800
@@ -1086,6 +1086,54 @@
};
}
+sub thread_has_subscription {
+ my ( $comment, $remote, $u ) = @_;
+
+ my @unknown_tracking_status;
+ my $watched = 0;
+
+ while ( $comment && $comment->valid && $comment->parenttalkid ) {
+ # check cache
+ $comment->{_watchedby} ||= {};
+ my $thread_watched = $comment->{_watchedby}->{$u->{userid}};
+
+ my $had_cached = defined $thread_watched;
+
+ unless ( $had_cached ) {
+ $thread_watched = $remote->has_subscription(
+ event => "JournalNewComment",
+ journal => $u,
+ arg2 => $comment->parenttalkid,
+ require_active => 1,
+ );
+ }
+
+ if ( $thread_watched ) {
+ $watched = 1;
+
+ # we had to go up a couple of levels before we could figure out
+ # whether we were watching or not
+ # so fix the status of intervening levels
+ foreach ( @unknown_tracking_status ) {
+ my $c = LJ::Comment->new( $u, dtalkid => $_ );
+ $c->{_watchedby}->{$u->{userid}} = $thread_watched;
+ }
+ @unknown_tracking_status = ();
+ }
+
+ # cache in this comment object if it's being watched by this user
+ $comment->{_watchedby}->{$u->{userid}} = $thread_watched;
+
+ # shortcircuit and stop going up the tree because:
+ last if $thread_watched; # current comment is watched
+ last if $had_cached; # we've been to this section of the ancestor tree already
+
+ push @unknown_tracking_status, $comment->dtalkid;
+ $comment = $comment->parent;
+ }
+
+ return $watched;
+}
sub indent {
return LJ::Talk::Post::indent(@_);
}
diff -r 116559a9f5bb -r 40cdb938430c cgi-bin/LJ/S2.pm
--- a/cgi-bin/LJ/S2.pm Tue May 17 10:20:10 2011 +0800
+++ b/cgi-bin/LJ/S2.pm Tue May 17 10:38:49 2011 +0800
@@ -3271,24 +3271,7 @@
# in other words, the user is not subscribed to this particular comment
# see if any parents are being watched
- my $watching_parent = 0;
- while ($comment && $comment->valid && $comment->parenttalkid) {
- # check cache
- $comment->{_watchedby} ||= {};
- my $thread_watched = $comment->{_watchedby}->{$u->{userid}};
-
- # not cached
- if (! defined $thread_watched) {
- $thread_watched = $remote->has_subscription(journal => $u, event => "JournalNewComment", arg2 => $comment->parenttalkid);
- }
-
- $watching_parent = 1 if ($thread_watched);
-
- # cache in this comment object if it's being watched by this user
- $comment->{_watchedby}->{$u->{userid}} = $thread_watched;
-
- $comment = $comment->parent;
- }
+ my $watching_parent = $comment->thread_has_subscription( $remote, $u );
my $etypeid = 'LJ::Event::JournalNewComment'->etypeid;
my %subparams = (
diff -r 116559a9f5bb -r 40cdb938430c htdocs/talkread.bml
--- a/htdocs/talkread.bml Tue May 17 10:20:10 2011 +0800
+++ b/htdocs/talkread.bml Tue May 17 10:38:49 2011 +0800
@@ -535,28 +535,7 @@
$track_img = 'track_active';
} else {
# see if any parents are being watched
- while ($comment && $comment->valid && $comment->parenttalkid) {
- # check cache
- $comment->{_watchedby} ||= {};
- my $thread_watched = $comment->{_watchedby}->{$u->{userid}};
-
- # not cached
- if (! defined $thread_watched) {
- $thread_watched = $remote->has_subscription(
- event => "JournalNewComment",
- journal => $u,
- arg2 => $comment->parenttalkid,
- require_active => 1,
- );
- }
-
- $track_img = 'track_thread_active' if ($thread_watched);
-
- # cache in this comment object if it's being watched by this user
- $comment->{_watchedby}->{$u->{userid}} = $thread_watched;
-
- $comment = $comment->parent;
- }
+ $track_img = 'track_thread_active' if $comment->thread_has_subscription( $remote, $u );
}
my $track_url = "$LJ::SITEROOT/manage/tracking/comments?journal=$u->{'user'}&talkid=$dtid";
diff -r 116559a9f5bb -r 40cdb938430c t/subscription-nested.t
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/t/subscription-nested.t Tue May 17 10:38:49 2011 +0800
@@ -0,0 +1,86 @@
+use strict;
+use Test::More;
+use lib "$ENV{LJHOME}/cgi-bin";
+require 'ljlib.pl';
+
+use LJ::Comment;
+use LJ::Talk;
+use LJ::Test qw( temp_user );
+
+sub check_thread_subscription {
+ my ( $entry, $u, $no_sub ) = @_;
+
+ subtest "checking thread subscription" => sub {
+ my $time = time();
+ my @comments = $entry->comment_list;
+
+ foreach my $comment ( @comments ) {
+ my $time = time();
+ my $has_sub = $comment->thread_has_subscription( $u, $entry->journal );
+
+ if ( $no_sub->{$comment->jtalkid} ) {
+ ok( ! $has_sub, $no_sub->{$comment->jtalkid} );
+ } else {
+ ok( $has_sub, "ancestor of " . $comment->jtalkid . " is tracked" );
+ }
+ }
+ }
+}
+
+note("shallow comment threads");
+{
+ my $u = temp_user();
+ my $e = $u->t_post_fake_entry;
+
+ my @comments;
+ my $c = $e->t_enter_comment;
+ push @comments, $c;
+
+ foreach ( 1...10 ) {
+ $c = $c->t_reply;
+ push @comments, $c;
+ }
+
+ $u->subscribe( event => "JournalNewComment",
+ method => "Email",
+ journal => $u,
+ arg2 => $comments[2]->jtalkid,
+ );
+
+ check_thread_subscription( $e, $u, {
+ # not subscribed to # because....
+ 1 => "above subscription point",
+ 2 => "above subscription point",
+ 3 => "subscribed starting from this comment (but not subscribed to ancestor)",
+ } );
+}
+
+note("deep comment thread");
+{
+ my $u = temp_user();
+ my $e = $u->t_post_fake_entry;
+
+ my @comments;
+ my $c = $e->t_enter_comment;
+ push @comments, $c;
+
+ foreach ( 1...500 ) {
+ $c = $c->t_reply;
+ push @comments, $c;
+ }
+
+ $u->subscribe( event => "JournalNewComment",
+ method => "Email",
+ journal => $u,
+ arg2 => $comments[2]->jtalkid,
+ );
+
+ check_thread_subscription( $e, $u, {
+ # not subscribed to # because....
+ 1 => "above subscription point",
+ 2 => "above subscription point",
+ 3 => "subscribed starting from this comment (but not subscribed to ancestor)",
+ } );
+}
+
+done_testing();
--------------------------------------------------------------------------------
