Андрей (andy) wrote in changelog,
Андрей
andy
changelog

[livejournal] r21390: LJSUP-11496 (optimize get_daycounts for ...

Committer: ailyin
LJSUP-11496 (optimize get_daycounts for ONTD)
U   trunk/cgi-bin/LJ/User.pm
Modified: trunk/cgi-bin/LJ/User.pm
===================================================================
--- trunk/cgi-bin/LJ/User.pm	2012-03-13 09:47:39 UTC (rev 21389)
+++ trunk/cgi-bin/LJ/User.pm	2012-03-13 10:35:27 UTC (rev 21390)
@@ -8230,9 +8230,12 @@
     ## get lock to prevent multiple apache processes to execute the sql below.
     ## one process runs, the other wait for results 
     my $release_lock = sub {
-        $dbcr->selectrow_array("SELECT RELEASE_LOCK('$memkey')");
+        $dbcr->do( 'SELECT RELEASE_LOCK(?)', undef, $memkey->[1] );
     };
-    my $locked = $dbcr->selectrow_array("SELECT GET_LOCK('$memkey',10)");
+
+    my ($locked) = $dbcr->selectrow_array(
+        'SELECT GET_LOCK(?,10)', undef, $memkey->[1] );
+
     return unless $locked; ## 10 seconds expired
 
     $list = LJ::MemCache::get($memkey);
@@ -8303,40 +8306,50 @@
     ## is the time of the creation of the list. The memcache is
     ## invalid if there are new entries in journal since that time.
     ##
-    my $memkey = [ $u->userid,
-        join( ':', 'dayct3', 'month', $year, $month, $u->userid, @$kind ) ];
+    my $memkey_base =
+        join( ':', 'dayct3', 'month', $year, $month, $u->userid, @$kind );
+    my $memkey = [ $u->userid, $memkey_base ];
+    my $memlockkey = [ $u->userid, $memkey_base . ':lock' ];
 
+    my $lock_acquired = 0;
+
+    my $lock = sub {
+        return if $lock_acquired;
+        $lock_acquired = 1;
+
+        return LJ::MemCache::add( $memlockkey, 1, 2 );
+    };
+
+    my $unlock = sub {
+        LJ::MemCache::delete($memlockkey);
+        $lock_acquired = 0;
+    };
+
     my $list = LJ::MemCache::get($memkey);
     if ($list) {
         my $list_create_time = shift @$list;
+        my $list_exptime     = shift @$list;
 
+        my $need_recalculate = 0;
+
         my $timeupdate       = $u->timeupdate;
         my $timeupdate_year  = ( gmtime $timeupdate )[5] + 1900;
         my $timeupdate_month = ( gmtime $timeupdate )[4] + 1;
 
-        return $list if $timeupdate_year != $year ||
-            $timeupdate_month != $month ||
-            $u->timeupdate <= $list_create_time;
-    }
+        $need_recalculate = 1
+            if $timeupdate_year == $year &&
+            $timeupdate_month == $month &&
+            $u->timeupdate > $list_create_time;
 
-    my $dbcr = LJ::get_cluster_def_reader($u) or return;
-    
-    ## get lock to prevent multiple apache processes to execute the sql below.
-    ## one process runs, the other wait for results 
-    my $release_lock = sub {
-        $dbcr->selectrow_array("SELECT RELEASE_LOCK('$memkey')");
-    };
-    my $locked = $dbcr->selectrow_array("SELECT GET_LOCK('$memkey',10)");
-    return unless $locked; ## 10 seconds expired
+        if ($need_recalculate) {
+            $need_recalculate = 0 unless $lock->();
+        }
 
-    $list = LJ::MemCache::get($memkey);
-    if ($list) {
-        ## other process may have filled the data while we waited for the lock
-        my $list_create_time = shift @$list;
-        $release_lock->();
-        return $list;
+        return $list unless $need_recalculate;
     }
 
+    return [] unless $lock->();
+
     my ( $selecttype, $gmask ) = @$kind;
     my $secwhere;
     if ( $selecttype eq 'all' ) {
@@ -8348,6 +8361,8 @@
             "(security='usemask' AND allowmask & $gmask) )";
     }
 
+    my $dbcr = LJ::get_cluster_def_reader($u);
+    
     my $sth = $dbcr->prepare("SELECT day, COUNT(*) ".
                              "FROM log2 WHERE journalid=? $secwhere AND " .
                              "year=? AND month=? " .
@@ -8360,10 +8375,10 @@
         push @$days, [ int($year), int($month), int($d), int($c) ];
     }
 
-    my $exptime = 3600 + int( rand(3600) );
-    LJ::MemCache::set( $memkey, [time, @$days], $exptime );
+    my $exptime = time + 3600 + int( rand(3600) );
+    LJ::MemCache::set( $memkey, [ time, $exptime, @$days ] );
 
-    $release_lock->();
+    $unlock->();
     return $days;
 }
 

Tags: ailyin, andy, livejournal, pm
Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments