[livejournal] r21957: LJSUP-12198: Delayed entry duplication c...
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;
}
