[dw-free] New dversion for userpics to make renaming userpics faster
[commit: http://hg.dwscoalition.org/dw-free/rev/7b8044812951]
http://bugs.dwscoalition.org/show_bug.cgi?id=3064
Better, faster userpic renames, done by updating at most three rows in
userpicmap3. We'll be slowly rolling out the ability to rename again post
codepush.
Patch by
exor674.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=3064
Better, faster userpic renames, done by updating at most three rows in
userpicmap3. We'll be slowly rolling out the ability to rename again post
codepush.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- bin/worker/userpic-rename
- cgi-bin/DW/Worker/UserpicRenameWorker.pm
- cgi-bin/LJ/Userpic.pm
- htdocs/editicons.bml
-------------------------------------------------------------------------------- diff -r 2ee31e71f90c -r 7b8044812951 bin/worker/userpic-rename --- a/bin/worker/userpic-rename Sun Oct 03 21:26:08 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -#!/usr/bin/perl -# -# bin/worker/userpic-rename -# -# TheSchwartz worker for renaming userpics -# -# Authors: -# Allen Petersen <allen@suberic.net> -# -# Copyright (c) 2009 by Dreamwidth Studios, LLC. -# -# This program is free software; you may redistribute it and/or modify it under -# the same terms as Perl itself. For a copy of the license, please reference -# 'perldoc perlartistic' or 'perldoc perlgpl'. - -use strict; -use warnings; - -use lib "$ENV{LJHOME}/cgi-bin"; -use LJ::Worker::TheSchwartz; -use DW::Worker::UserpicRenameWorker; - -foreach my $capability (DW::Worker::UserpicRenameWorker->schwartz_capabilities) { - schwartz_decl( $capability ); -} - -schwartz_work(); # Never returns. diff -r 2ee31e71f90c -r 7b8044812951 cgi-bin/DW/Worker/UserpicRenameWorker.pm --- a/cgi-bin/DW/Worker/UserpicRenameWorker.pm Sun Oct 03 21:26:08 2010 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -#!/usr/bin/perl -# -# DW::Worker::UserpicRenameWorker -# -# TheSchwartz worker module for renaming userpics. Called with -# LJ::theschwartz()->insert('DW::Worker::UserpicRenameWorker', { -# 'uid' => $u->userid, 'keywordmap' => Storable::nfreeze(\%keywordmap); -# -# Authors: -# Allen Petersen <allen@suberic.net> -# -# Copyright (c) 2009 by Dreamwidth Studios, LLC. -# -# This program is free software; you may redistribute it and/or modify it under -# the same terms as Perl itself. For a copy of the license, please reference -# 'perldoc perlartistic' or 'perldoc perlgpl'. - -package DW::Worker::UserpicRenameWorker; - -use strict; -use warnings; -use base 'TheSchwartz::Worker'; - -sub schwartz_capabilities { return ('DW::Worker::UserpicRenameWorker'); } - -sub keep_exit_status_for { 86400 } # 24 hours - -my $logpropid; -my $talkpropid; - -sub work { - my ($class, $job) = @_; - - my $arg = $job->arg; - - my ($uid, $keywordmapstring) = map { delete $arg->{$_} } qw( uid keywordmap ); - - return $job->permanent_failure("Unknown keys: " . join(", ", keys %$arg)) - if keys %$arg; - return $job->permanent_failure("Missing argument") - unless defined $uid && defined $keywordmapstring; - - my $keywordmap = eval { Storable::thaw($keywordmapstring) } or return $job->failed("Failed to load keywordmap from arg '$keywordmapstring': " . $@); - - # get the user from the uid - my $u = LJ::want_user($uid) or return $job->failed("Unable to load user with uid $uid"); - - # only get the propids once; they're not going to change - unless ($logpropid && $talkpropid) { - $logpropid = LJ::get_prop( log => 'picture_keyword' )->{id}; - $talkpropid = LJ::get_prop( talk => 'picture_keyword' )->{id}; - } - - # only update 1000 rows at a time. - my $LIMIT = 1000; - - # now we go through each cluster and update the logprop2 and talkprop2 - # tables with the new values. - foreach my $cluster_id (@LJ::CLUSTERS) { - my $dbcm = LJ::get_cluster_master($cluster_id); - - foreach my $kw (keys %$keywordmap) { - # find entries for clearing cache - my $matches = $dbcm->selectall_arrayref(q{ - SELECT log2.journalid AS journalid, - log2.jitemid AS jitemid - FROM logprop2 - INNER JOIN log2 - ON ( logprop2.journalid = log2.journalid - AND logprop2.jitemid = log2.jitemid ) - WHERE posterid = ? - AND propid=? - AND value = ? - }, undef, $u->id, $logpropid, $kw); - - # update entries - my $updateresults = $LIMIT; - while ($updateresults == $LIMIT) { - $updateresults = $dbcm->do( q{ - UPDATE logprop2 - SET value = ? - WHERE propid=? - AND value = ? - AND EXISTS ( - SELECT posterid - FROM log2 - WHERE log2.journalid = logprop2.journalid - AND log2.jitemid = logprop2.jitemid - AND log2.posterid = ? ) - LIMIT ? - }, undef, $keywordmap->{$kw}, $logpropid, $kw, $u->id, $LIMIT); - return $job->permanent_failure($dbcm->errstr) if $dbcm->err; - } - - # clear cache - foreach my $match (@$matches) { - LJ::MemCache::delete([ $match->[0], "logprop:" . $match->[0]. ":" . $match->[1] ]); - } - - # update comments - # find comments for clearing cache - $matches = $dbcm->selectall_arrayref( q{ - SELECT talkprop2.journalid AS journalid, - talkprop2.jtalkid AS jtalkid - FROM talkprop2 - INNER JOIN talk2 - ON ( talkprop2.journalid = talk2.journalid - AND talkprop2.jtalkid = talk2.jtalkid ) - WHERE posterid = ? - AND tpropid=? - AND value = ? - }, undef, $u->id, $talkpropid, $kw); - - # update coments - $updateresults = $LIMIT; - while ($updateresults == $LIMIT) { - $updateresults = $dbcm->do( q{ - UPDATE talkprop2 - SET value = ? - WHERE tpropid=? - AND value = ? - AND EXISTS ( - SELECT posterid - FROM talk2 - WHERE talk2.journalid = talkprop2.journalid - AND talk2.jtalkid = talkprop2.jtalkid - AND talk2.posterid = ? ) - LIMIT ? - }, undef, $keywordmap->{$kw}, $talkpropid, $kw, $u->id, $LIMIT); - return $job->permanent_failure($dbcm->errstr) if $dbcm->err; - } - - # clear cache - foreach my $match (@$matches) { - LJ::MemCache::delete([ $match->[0], "talkprop:" . $match->[0]. ":" . $match->[1] ]); - } - } - } - - $job->completed; -} - -1; diff -r 2ee31e71f90c -r 7b8044812951 cgi-bin/LJ/Userpic.pm --- a/cgi-bin/LJ/Userpic.pm Sun Oct 03 21:26:08 2010 +0800 +++ b/cgi-bin/LJ/Userpic.pm Sun Oct 03 22:39:08 2010 +0800 @@ -1142,19 +1142,13 @@ sub set_keywords { # all new keywords must not currently be in use; you can't rename a keyword # to a keyword currently mapped to another (or the same) userpic. this will # result in an error and no changes made to these keywords. -# -# the setting of new keywords is done by Userpic->set_keywords; the remapping -# of existing pics is done asynchonously via TheSchwartz using the -# DW::Worker::UserpicRenameWorker. sub set_and_rename_keywords { my ( $self, $new_keyword_string, $orig_keyword_string ) = @_; - my $sclient = LJ::theschwartz(); - - # error out if TheSchwartz isn't available. + my $u = $self->owner; LJ::errobj("Userpic::RenameKeywords", - origkw => $orig_keyword_string, - newkw => $new_keyword_string)->throw unless $sclient; + origkw => $orig_keyword_string, + newkw => $new_keyword_string)->throw unless LJ::is_enabled( "icon_renames" ) || $u->userpic_have_mapid; my @keywords = split(',', $new_keyword_string); my @orig_keywords = split(',', $orig_keyword_string); @@ -1190,28 +1184,45 @@ sub set_and_rename_keywords { if (keys(%keywordmap)) { #make sure that none of the target keywords already exist. - my $u = $self->owner; foreach my $kw ( values %keywordmap ) { if ( $u && $u->get_picid_from_keyword( $kw, -1 ) != -1 ) { LJ::errobj( "Userpic::RenameKeywordExisting", keyword => $kw )->throw; } } - - # set the keywords for this userpic to the new set of keywords - $self->set_keywords(@keywords); - - # send to TheSchwartz to do the actual renaming - my $job = TheSchwartz::Job->new_from_array( - 'DW::Worker::UserpicRenameWorker', { - 'uid' => $u->userid, - 'keywordmap' => Storable::nfreeze(\%keywordmap) } ); - - unless ($job && $sclient->insert($job)) { - LJ::errobj("Userpic::RenameKeywords", - origkw => $orig_keyword_string, - newkw => $new_keyword_string)->throw; + + while (my ($origkw, $newkw) = each( %keywordmap )) { + + # need to check if the kwid already has a mapid + my $mapid = $u->get_mapid_from_keyword( $newkw ); + + # if it does, we have to remap it + if ( $mapid ) { + my $oldid = $u->get_mapid_from_keyword( $origkw ); + + # redirect the old mapid to the new mapid + $u->do( "UPDATE userpicmap3 SET kwid = NULL, picid = NULL, redirect_mapid = ? WHERE mapid = ? AND userid = ?", + undef, $mapid, $oldid, $u->id ); + die $u->errstr if $u->err; + + # change any redirects pointing to the old mapid to the new mapid + $u->do( "UPDATE userpicmap3 SET redirect_mapid = ? WHERE redirect_mapid = ? AND userid = ?", + undef, $mapid, $oldid, $u->id ); + die $u->errstr if $u->err; + + # and set the new mapid to point to the picture + $u->do( "UPDATE userpicmap3 SET picid = ? WHERE mapid = ? AND userid = ?", + undef, $self->picid, $mapid, $u->id ); + die $u->errstr if $u->err; + + } else { + $u->do( "UPDATE userpicmap3 SET kwid = ? WHERE kwid = ? AND userid = ?", + undef, $u->get_keyword_id( $newkw ), $u->get_keyword_id( $origkw ), $u->id ); + die $u->errstr if $u->err; + } } + LJ::Userpic->delete_cache($u); + $u->clear_userpic_kw_map; } return 1; diff -r 2ee31e71f90c -r 7b8044812951 htdocs/editicons.bml --- a/htdocs/editicons.bml Sun Oct 03 21:26:08 2010 +0800 +++ b/htdocs/editicons.bml Sun Oct 03 22:39:08 2010 +0800 @@ -90,6 +90,8 @@ use strict; my $factory_redirect; my $no_errors = 1; my $success_count = 0; + + my $display_rename = LJ::is_enabled( "icon_renames" ) ? 1 : 0 ; ### save/update mode if (LJ::did_post()) { @@ -508,7 +510,6 @@ use strict; $body .= "</div>"; $body .= "<div id='list_userpics' style='width: 98%; float: left;'>"; - my $display_rename = LJ::theschwartz() ? 1 : 0; if ( $keyword_sort ) { @userpics = LJ::Userpic->sort( \@userpics ); @@ -537,7 +538,7 @@ use strict; if ($display_rename) { $body .= "<div id='rename_div_$pid' class='userpic_rename pkg'>\n"; $body .= "<script type='text/javascript'>document.getElementById('rename_div_$pid').style.display = 'none';</script>\n"; - if ( LJ::is_enabled( "icon_renames" ) ) { + if ( $u->userpic_have_mapid ) { $body .= LJ::html_check({ 'type' => 'checkbox', 'name' => "rename_keyword_$pid", 'class' => "checkbox", 'id' => "rename_keyword_$pid", 'value' => 1, 'disabled' => $LJ::DISABLE_MEDIA_UPLOADS }); @@ -625,18 +626,19 @@ sub update_userpics my $u = shift; my @userpics = @$userpicsref; my $err = shift; - - + + my $display_rename = LJ::is_enabled( "icon_renames" ) ? 1 : 0 ; + # form being posted isn't multipart, since we were able to read from %POST unless (LJ::check_form_auth()) { return $err->($ML{'error.invalidform'}); } - + my @delete; # userpic objects to delete my @inactive_picids; my %picid_of_kwid; my %used_keywords; - + # we need to count keywords based on what the user provided, in order # to find duplicates. $up->keywords doesn't work, because re-using a # keyword will remove it from the other userpic without our knowing @@ -668,8 +670,8 @@ sub update_userpics if ($POST{"kw_$picid"} ne $POST{"kw_orig_$picid"}) { my $kws = $POST{"kw_$picid"}; - if ($POST{"rename_keyword_$picid"}) { - if ( LJ::is_enabled( "icon_renames" ) ) { + if ( $POST{"rename_keyword_$picid"} ) { + if ( $display_rename && $u->userpic_have_mapid ) { eval { $up->set_and_rename_keywords($kws, $POST{"kw_orig_$picid"}); } or push @errors, $@->as_html; --------------------------------------------------------------------------------
no subject