fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2011-06-14 07:51 am

[dw-free] Cache paid status

[commit: http://hg.dwscoalition.org/dw-free/rev/bcc06dfd8d7e]

http://bugs.dwscoalition.org/show_bug.cgi?id=3677

Cache the paid status on the request, so that we don't hit the database
multiple times in one page load unnecessarily.

Patch by [personal profile] exor674.

Files modified:
  • bin/worker/paidstatus
  • cgi-bin/DW/Pay.pm
  • cgi-bin/ljlib.pl
--------------------------------------------------------------------------------
diff -r 3ef06a227ab1 -r bcc06dfd8d7e bin/worker/paidstatus
--- a/bin/worker/paidstatus	Mon Jun 13 18:50:24 2011 +0800
+++ b/bin/worker/paidstatus	Tue Jun 14 15:50:58 2011 +0800
@@ -96,6 +96,7 @@
 sub main_loop {
     # disconnect dbs
     LJ::disconnect_dbs();
+    LJ::start_request();
 
     # now get a db or die
     my $dbh = LJ::get_db_writer()
diff -r 3ef06a227ab1 -r bcc06dfd8d7e cgi-bin/DW/Pay.pm
--- a/cgi-bin/DW/Pay.pm	Mon Jun 13 18:50:24 2011 +0800
+++ b/cgi-bin/DW/Pay.pm	Tue Jun 14 15:50:58 2011 +0800
@@ -109,13 +109,17 @@
 sub get_paid_status {
     DW::Pay::clear_error();
 
-    my $uuid = shift;
+    my ( $uuid, %opts ) = @_;
     my $uid;
 
+    my $use_cache = ! $opts{no_cache};
+
     $uid = LJ::want_userid( $uuid ) if defined $uuid;
     return error( ERR_FATAL, "Invalid user object/userid passed in." )
         unless defined $uid && $uid > 0;
 
+    return $LJ::PAID_STATUS{$uid} if $use_cache && $LJ::PAID_STATUS{$uid};
+
     my $dbr = DW::Pay::get_db_reader()
         or return error( ERR_TEMP, "Failed acquiring database reader handle." );
     my $row = $dbr->selectrow_hashref( q{
@@ -126,6 +130,7 @@
     return error( ERR_FATAL, "Database error: " . $dbr->errstr )
         if $dbr->err;
 
+    $LJ::PAID_STATUS{$uid} = $row;
     return $row;
 }
 
@@ -387,7 +392,7 @@
     $amonths = 0 if $permanent;
 
     # if they have a $ps hashref, they have or had paid time at some point
-    if ( my $ps = DW::Pay::get_paid_status( $u ) ) {
+    if ( my $ps = DW::Pay::get_paid_status( $u, no_cache => 1 ) ) {
         # easy bail if they're permanent
         return error( ERR_FATAL, 'User is already permanent, cannot apply more time.' )
             if $ps->{permanent};
@@ -483,13 +488,14 @@
         or return error( ERR_FATAL, "Invalid/not a user object." );
     my %cols = ( @_ )
         or return error( ERR_FATAL, "Nothing to change!" );
+    delete $LJ::PAID_STATUS{$u->id};
 
     my $dbh = DW::Pay::get_db_writer()
         or return error( ERR_TEMP, "Unable to get db writer." );
 
     # don't let them add months if the user expired, convert it to set months
     if ( $cols{_add_months} ) {
-        my $row = DW::Pay::get_paid_status( $u );
+        my $row = DW::Pay::get_paid_status( $u, no_cache => 1 );
         if ( $row && $row->{expiresin} > 0 ) {
             my $time = $dbh->selectrow_array( "SELECT UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME($row->{expiretime}), " .
                                               "INTERVAL $cols{_add_months} MONTH))" );
@@ -580,7 +586,7 @@
         or return error( ERR_FATAL, "Invalid/not a user object." );
     my $datetime = shift();
 
-    my $ps = DW::Pay::get_paid_status( $u );
+    my $ps = DW::Pay::get_paid_status( $u, no_cache => 1 );
     return error( ERR_FATAL, "Can't set expiration date for this type of account" )
         if $ps->{expiresin} <= 0 || $ps->{permanent};
 
@@ -596,6 +602,7 @@
     $dbh->do( q{UPDATE dw_paidstatus SET expiretime=? WHERE userid=?}, undef, $row->{datetime}, $u->id );
     return error( ERR_FATAL, "Database error: " . $dbh->errstr )
         if $dbh->err;
+    delete $LJ::PAID_STATUS{$u->id};
     return 1;
 }
 
diff -r 3ef06a227ab1 -r bcc06dfd8d7e cgi-bin/ljlib.pl
--- a/cgi-bin/ljlib.pl	Mon Jun 13 18:50:24 2011 +0800
+++ b/cgi-bin/ljlib.pl	Tue Jun 14 15:50:58 2011 +0800
@@ -1270,6 +1270,9 @@
     $LJ::ADV_PER_PAGE = 0;            # Counts ads displayed on a page
     $LJ::ACTIVE_RES_GROUP = undef;    # use whatever is current site default
 
+
+    %LJ::PAID_STATUS = ();            # per-request paid status
+
     $LJ::CACHE_REMOTE_BOUNCE_URL = undef;
     LJ::Userpic->reset_singletons;
     LJ::Comment->reset_singletons;
--------------------------------------------------------------------------------