Committer: sbelyaev
LJSUP-12198: Delayed entry duplication check fix.U trunk/cgi-bin/LJ/DelayedEntry.pm U trunk/cgi-bin/ljprotocol.pl
Modified: trunk/cgi-bin/LJ/DelayedEntry.pm =================================================================== --- trunk/cgi-bin/LJ/DelayedEntry.pm 2012-05-15 09:08:26 UTC (rev 21956) +++ trunk/cgi-bin/LJ/DelayedEntry.pm 2012-05-15 11:16:01 UTC (rev 21957) @@ -109,6 +109,7 @@ $delayedid, $data_ser ); + my $memcache_key = "delayed_entry:$journalid:$delayedid"; LJ::MemCache::set($memcache_key, $data_ser, 3600); @@ -120,6 +121,7 @@ $self->{delayed_id} = $delayedid; $self->{default_dateformat} = $opts->{'dateformat'} || 'S2'; + $self->__set_mark($req); __statistics_absorber($journal, $poster); return $self; @@ -191,6 +193,7 @@ $data_ser, $journalid, $delayedid ); $self->{data} = $req; + $self->__set_mark($journalid, $posterid, $delayedid, $req); my $memcache_key = "delayed_entry:$journalid:$delayedid"; LJ::MemCache::set($memcache_key, $data_ser, 3600); } @@ -1016,6 +1019,22 @@ return $relcount ? 1 : 0; } +sub dupsig_check { + my ($class, $journal, $posterid, $req) = @_; + + my $signature = __get_mark($journal->userid, $posterid); + return unless $signature; + + my @parts = split(/:/, $signature); + my $current_signature = __signature($req); + + if ($current_signature eq $parts[0]) { + my $delayedid = $parts[1]; + return LJ::DelayedEntry->get_entry_by_id( $journal, + $delayedid ); + } +} + sub __delayed_entry_can_see { my ( $uowner, $poster ) = @_; @@ -1136,6 +1155,34 @@ (LJ::MemCache::add($stat_key, 0), LJ::MemCache::incr($stat_key, 1)); } + +sub __get_mark { + my ($journalid, $posterid, $req) = @_; + + my $memcache_key = "delayed_entry_dup:$journalid:$posterid"; + my ($postsig) = LJ::MemCache::get($memcache_key); + + return $postsig; +} + +sub __set_mark { + my ($self, $req) = @_; + my $signature = __signature($req) . ":" . $self->delayedid; + + my $journalid = $self->journalid; + my $posterid = $self->posterid; + + my $memcache_key = "delayed_entry_dup:$journalid:$posterid"; + LJ::MemCache::set($memcache_key, $signature, 35); +} + +sub __signature { + my ($req) = @_; + my $dupsig = Digest::MD5::md5_hex(join('', map { $req->{$_} } + qw(subject event usejournal security allowmask))); + return $dupsig; +} + sub __serialize { my ($req) = @_; __assert($req, "no request"); Modified: trunk/cgi-bin/ljprotocol.pl =================================================================== --- trunk/cgi-bin/ljprotocol.pl 2012-05-15 09:08:26 UTC (rev 21956) +++ trunk/cgi-bin/ljprotocol.pl 2012-05-15 11:16:01 UTC (rev 21957) @@ -2428,7 +2428,7 @@ my $res_done = 0; # set true by getlock when post was duplicate, or error getting lock my $getlock = sub { - my $delayed = @_; + my ($delayed) = @_; my $r = $dbcm->selectrow_array("SELECT GET_LOCK(?, 2)", undef, $lock_key); unless ($r) { $res = undef; # a failure case has an undef result @@ -2436,35 +2436,34 @@ $res_done = 1; # tell caller to bail out return; } - + + if ($delayed) { + my $entry = LJ::DelayedEntry->dupsig_check($uowner, $posterid, $req); + if (!$entry) { + return; + } + + $res->{'delayedid'} = $entry->delayedid; + $res->{'type'} = 'delayed'; + $res->{'url'} = $entry->url; + + $res_done = 1; + $release->(); + } + LJ::load_user_props($u, { use_master => 1, reload => 1 }, 'dupsig_post'); - + my @parts = split(/:/, $u->{'dupsig_post'}); if ($parts[0] eq $dupsig) { # duplicate! let's make the client think this was just the # normal firsit response. - if ($delayed) { - my $delayedid = $parts[1]; - my $entry = LJ::DelayedEntry->get_entry_by_id($uowner, $delayedid); - if (!$entry) { - return; - } + $res->{'itemid'} = $parts[1]; + $res->{'anum'} = $parts[2]; - $res->{'delayedid'} = $delayedid; - $res->{'type'} = 'delayed'; - $res->{'url'} = $entry->url; - } else { - $res->{'itemid'} = $parts[1]; - $res->{'anum'} = $parts[2]; - unless (defined $res->{'anum'}) { - return; - } - - my $dup_entry = LJ::Entry->new($uowner, jitemid => $res->{'itemid'}, anum => $res->{'anum'}); - $res->{'url'} = $dup_entry->url; - } - + my $dup_entry = LJ::Entry->new($uowner, jitemid => $res->{'itemid'}, anum => $res->{'anum'}); + $res->{'url'} = $dup_entry->url; + $res_done = 1; $release->(); } @@ -2519,7 +2518,6 @@ $res->{'type'} = 'delayed'; $res->{'url'} = $entry->url; - $u->set_prop( {"dupsig_post" => "$dupsig:" . $entry->delayedid . ":0"} ); $release->(); return $res; }