Committer: amyshkin
LJSUP-9804: Problem with writing properties data for entries on Omega/Alpha/Beta serversU trunk/cgi-bin/LJ/Entry.pm U trunk/cgi-bin/LJ/User/PropStorage/DB.pm U trunk/cgi-bin/LJ/User/PropStorage.pm U trunk/cgi-bin/ljlib.pl
Modified: trunk/cgi-bin/LJ/Entry.pm =================================================================== --- trunk/cgi-bin/LJ/Entry.pm 2011-09-16 09:07:59 UTC (rev 20063) +++ trunk/cgi-bin/LJ/Entry.pm 2011-09-16 09:17:44 UTC (rev 20064) @@ -351,14 +351,14 @@ # @entries - array of LJ::Entry objects # # See also instance method '_load_props' -# +# sub preload_props { my ($class, $entlist) = @_; - - ## %needed_to_load: userid --> [LJ::Entry, LJ::Entry, ... ] + + ## %needed_to_load: userid --> [LJ::Entry, LJ::Entry, ... ] ## %users: userid --> LJ::User - my (%needed_to_load, %users); - + my (%needed_to_load, %users); + foreach my $en (@$entlist) { next if $en->{_loaded_props}; my $u = $en->{u}; @@ -850,7 +850,7 @@ $opts->{journalid} = $self->journalid; $opts->{posterid} = $self->posterid; $opts->{entry_url} = $self->prop('reposted_from') || $self->url; - + $self->_load_text unless $self->{_loaded_text}; my $event = $self->{event}; LJ::CleanHTML::clean_event(\$event, $opts); @@ -930,7 +930,7 @@ my $poster = $self->poster; return 0 if $poster->{statusvis} eq 'S'; - # if poster choosed to delete jouranl and all external content, + # if poster choosed to delete jouranl and all external content, # then don't show his/her entries, except in some protected journals like 'lj_core' if ($poster->{statusvis} eq 'D') { my ($purge_comments, $purge_community_entries) = split /:/, $poster->prop("purge_external_content"); @@ -1398,7 +1398,7 @@ ## returns 'yes' if entry is ads-eligible (there are no offensive terms etc), and 'no' otherwise sub check_for_negative_terms { my $self = shift; - + my $tags = $self->prop('personifi_tags'); return $1 if $tags =~ /nterms:(\w+)/; my $nterms = ( ($self->subject_raw . ' '. $self->event_raw) =~ /($LJ::NEGATIVE_TERMS)/) ?'no':'yes'; @@ -1480,25 +1480,20 @@ my ($idsbyc, $type, $ret) = @_; my $opts = {}; - if ($type eq 'text') { $opts->{text_only} = 1; - } - elsif ($type eq 'prop') { + } elsif ($type eq 'prop') { $opts->{prop_only} = 1; - } - else { + } else { return undef; } my @postids; - while (my ($cid, $ids) = each %$idsbyc) { foreach my $pair (@$ids) { push @postids, [ $cid, $pair->[0], $pair->[1] ]; } } - my $rawposts = LJ::get_posts_raw($opts, @postids); # add replycounts fields to props @@ -1510,12 +1505,10 @@ # translate colon-separated (new) to space-separated (old) keys. $ret ||= {}; - while (my ($id, $data) = each %{$rawposts->{$type}}) { $id =~ s/:/ /; $ret->{$id} = $data; } - return $ret; } @@ -1653,21 +1646,17 @@ my $fetchprop = sub { my $db = shift; return unless %$cneedprop; - my $in = $make_in->(keys %$cneedprop); $sth = $db->prepare("SELECT journalid, jitemid, propid, value ". "FROM logprop2 WHERE $in"); $sth->execute; my %gotid; - while (my ($jid, $jitemid, $propid, $value) = $sth->fetchrow_array) { my $id = "$jid:$jitemid"; - LJ::load_props('log') unless defined LJ::MemCache::get('CACHE_PROPID'); - my $propname = LJ::MemCache::get('CACHE_PROPID')->{'log'}->{$propid}{name}; + my $propname = $LJ::CACHE_PROPID{'log'}->{$propid}{name}; $ret->{prop}{$id}{$propname} = $value; $gotid{$id} = 1; } - foreach my $id (keys %gotid) { my ($jid, $jitemid) = map { $_ + 0 } split(/:/, $id); LJ::MemCache::add([$jid, "logprop:$id"], $ret->{prop}{$id}); @@ -2229,12 +2218,10 @@ } } - # move reply count to props hash foreach ( keys %rc ) { $hashref->{$_}{'replycount'} = $rc{$_}; } - # return if all props loaded from memcached return unless %needprops || %needrc; unless ( $db ) { @@ -2243,7 +2230,6 @@ return unless $db; } - # if not all props loaded if ( %needprops ) { LJ::load_props("log"); my $in = join(",", keys %needprops); @@ -2251,23 +2237,19 @@ "WHERE journalid=? AND jitemid IN ($in)"); $sth->execute($userid); - my $propid = LJ::MemCache::get('CACHE_PROPID')->{'log'}; - while (my ($jitemid, $propid, $value) = $sth->fetchrow_array) { - $hashref->{$jitemid}->{ $propid->{$propid}->{'name'} } = $value; + $hashref->{$jitemid}->{$LJ::CACHE_PROPID{'log'}->{$propid}->{'name'}} = $value; } foreach my $id (keys %needprops) { - LJ::MemCache::set([$userid, "logprop:$userid:$id"], $hashref->{$id} || {}); - } + LJ::MemCache::set([$userid,"logprop:$userid:$id"], $hashref->{$id} || {}); + } } - # if not all reply counts loaded if (%needrc) { my $in = join(",", keys %needrc); my $sth = $db->prepare("SELECT jitemid, replycount FROM log2 WHERE journalid=? AND jitemid IN ($in)"); $sth->execute($userid); - while (my ($jitemid, $rc) = $sth->fetchrow_array) { $hashref->{$jitemid}->{'replycount'} = $rc; LJ::MemCache::add(LJ::Entry::reply_count_memkey($userid, $jitemid), $rc); @@ -2438,9 +2420,9 @@ my ($u, $jitemid, $action, $value) = @_; # check action name - die "unknown action: $action" + die "unknown action: $action" unless $action =~ /^(init)|(incr)|(decr)$/; - + $value = 1 unless defined $value; my $uid = $u->{'userid'}; my $memkey = LJ::Entry::reply_count_memkey($uid, $jitemid); @@ -2452,19 +2434,19 @@ } return 0 unless $u->writer; - + ## my $update_memc = $action eq 'decr' ? sub { LJ::MemCache::decr($memkey, $value) } : sub { LJ::MemCache::incr($memkey, $value) }; - + my $entry = LJ::Entry->new( $u, 'jitemid' => $jitemid ); LJ::run_hooks( 'replycount_change', $entry ); ## my $sql_sign = $action eq 'decr' ? '-' : '+'; my $sql = "UPDATE log2 SET replycount=LAST_INSERT_ID(replycount $sql_sign $value) WHERE journalid=? AND jitemid=?"; - + unless ( LJ::MemCache::can_gets() ){ # used Cache::Memcached driver that does not support 'gets' and 'cas' commands $u->selectrow_array("SELECT GET_LOCK(?,10)", undef, $memkey); @@ -2479,7 +2461,7 @@ } $u->selectrow_array("SELECT RELEASE_LOCK(?)", undef, $memkey); - + } else { # used Cache::Memcached::Fast @@ -2487,7 +2469,7 @@ LJ::run_hooks('report_entry_update', $uid, $jitemid); $u->do($sql, undef, $uid, $jitemid); if (@LJ::MEMCACHE_SERVERS and not defined $ret) { - ## Lock free update + ## Lock free update my $max_loops = 100; # prevent infinite loop while ($max_loops--){ my $gets = LJ::MemCache::gets($memkey); # get [cas, $val] @@ -2513,26 +2495,24 @@ my ($u, $jitemid, $action, $value) = @_; # check action name - die "unknown action: $action" + die "unknown action: $action" unless $action =~ /^(init)|(incr)|(decr)$/; - + return 0 unless $value; - + my $entry = LJ::Entry->new( $u, 'jitemid' => $jitemid ); my $spam_counter = $entry->prop('spam_counter') || 0; - + if ($action eq 'init') { $entry->set_prop('spam_counter', 0); return 1; - } - elsif ($action eq 'decr') { + } elsif ($action eq 'decr') { return 0 if $spam_counter - $value < 0; $entry->set_prop('spam_counter', $spam_counter - $value); - } - elsif ($action eq 'incr') { + } elsif ($action eq 'incr') { $entry->set_prop('spam_counter', $spam_counter + $value); } - + return 1; } Modified: trunk/cgi-bin/LJ/User/PropStorage/DB.pm =================================================================== --- trunk/cgi-bin/LJ/User/PropStorage/DB.pm 2011-09-16 09:07:59 UTC (rev 20063) +++ trunk/cgi-bin/LJ/User/PropStorage/DB.pm 2011-09-16 09:17:44 UTC (rev 20064) @@ -15,7 +15,6 @@ LJ::load_props('user'); my @propids; - foreach my $k (@$props) { my $propinfo = LJ::get_prop('user', $k); my $propid = $propinfo->{'id'}; @@ -23,20 +22,17 @@ push @propids, $propid; } - LJ::load_props('user') unless defined LJ::MemCache::get('CACHE_PROPID'); - my %propid_map = %{ LJ::MemCache::get('CACHE_PROPID')->{'user'} }; + my %propid_map = %{ $LJ::CACHE_PROPID{'user'} }; my %ret = map { $_ => undef } @$props; my $sql; - if ( my $propids_in = join(',', @propids) ) { $sql = qq{ SELECT upropid, value FROM $table WHERE userid=? AND upropid IN ($propids_in) }; - } - else { + } else { # well, it seems that they didn't pass us any props, so # let's use a somewhat different SQL query to load everything # from the given table Modified: trunk/cgi-bin/LJ/User/PropStorage.pm =================================================================== --- trunk/cgi-bin/LJ/User/PropStorage.pm 2011-09-16 09:07:59 UTC (rev 20063) +++ trunk/cgi-bin/LJ/User/PropStorage.pm 2011-09-16 09:17:44 UTC (rev 20064) @@ -137,8 +137,7 @@ my %ret; foreach my $propid (keys %$packed) { - LJ::load_props('user') unless defined LJ::MemCache::get('CACHE_PROPID'); - my $propname = LJ::MemCache::get('CACHE_PROPID')->{'user'}->{$propid}->{'name'}; + my $propname = $LJ::CACHE_PROPID{'user'}->{$propid}->{'name'}; next unless defined $propname; $ret{$propname} = $packed->{$propid}; } Modified: trunk/cgi-bin/ljlib.pl =================================================================== --- trunk/cgi-bin/ljlib.pl 2011-09-16 09:07:59 UTC (rev 20063) +++ trunk/cgi-bin/ljlib.pl 2011-09-16 09:17:44 UTC (rev 20064) @@ -1654,38 +1654,30 @@ # des-table: a list of tables' proplists to load. Can be one of # "log", "talk", "user", or "rate". # </LJFUNC> -sub load_props { +sub load_props +{ my $dbarg = ref $_[0] ? shift : undef; my @tables = @_; my $dbr; - my %keyname = ( - 'log' => 'propid', - 'talk' => 'tpropid', - 'user' => 'upropid', - 'rate' => 'rlid', - ); + my %keyname = qw(log propid + talk tpropid + user upropid + rate rlid + ); - my $prop = LJ::MemCache::get('CACHE_PROP'); - my $propid = LJ::MemCache::get('CACHE_PROPID'); - foreach my $t (@tables) { next unless defined $keyname{$t}; - next if defined $prop->{$t} && defined $propid->{$t}; - + next if defined $LJ::CACHE_PROP{$t}; my $tablename = $t eq "rate" ? "ratelist" : "${t}proplist"; $dbr ||= LJ::get_db_reader(); my $sth = $dbr->prepare("SELECT * FROM $tablename"); $sth->execute; - while (my $p = $sth->fetchrow_hashref) { $p->{'id'} = $p->{$keyname{$t}}; - $prop->{$t}->{$p->{'name'}} = $p; - $propid->{$t}->{$p->{'id'}} = $p; + $LJ::CACHE_PROP{$t}->{$p->{'name'}} = $p; + $LJ::CACHE_PROPID{$t}->{$p->{'id'}} = $p; } } - - LJ::MemCache::set('CACHE_PROP', $prop); - LJ::MemCache::set('CACHE_PROPID', $propid); } # <LJFUNC> @@ -1701,27 +1693,26 @@ # "log", "talk", or "user". # des-name: the name of the prop to get the hashref of. # </LJFUNC> -sub get_prop { +sub get_prop +{ my $table = shift; my $name = shift; - - my $prop = LJ::MemCache::get('CACHE_PROP'); - - unless (defined $prop->{$table} && $prop->{$table}->{$name}) { + unless (defined $LJ::CACHE_PROP{$table} && $LJ::CACHE_PROP{$table}->{$name}) { + $LJ::CACHE_PROP{$table} = undef; LJ::load_props($table); } - unless ($prop->{$table}) { + unless ($LJ::CACHE_PROP{$table}) { warn "Prop table does not exist: $table" if $LJ::IS_DEV_SERVER; return undef; } - unless ($prop->{$table}->{$name}) { - warn "Prop does not exist: $table - $name" if $LJ::IS_DEV_SERVER && $name ne 'replycount'; + unless ($LJ::CACHE_PROP{$table}->{$name}) { + warn "Prop does not exist: $table - $name" if $LJ::IS_DEV_SERVER; return undef; } - return LJ::MemCache::get('CACHE_PROP')->{$table}->{$name}; + return $LJ::CACHE_PROP{$table}->{$name}; } # <LJFUNC> @@ -1734,35 +1725,36 @@ # and their associated values being hashrefs to where you # want that data to be populated. # </LJFUNC> -sub load_codes { +sub load_codes +{ &nodb; my $req = shift; my $dbr = LJ::get_db_reader() or die "Unable to get database handle"; - foreach my $type (keys %{$req}) { + foreach my $type (keys %{$req}) + { my $memkey = "load_codes:$type"; - - unless ($LJ::CACHE_CODES{$type} ||= LJ::MemCache::get($memkey)) { + unless ($LJ::CACHE_CODES{$type} ||= LJ::MemCache::get($memkey)) + { $LJ::CACHE_CODES{$type} = []; my $sth = $dbr->prepare("SELECT code, item, sortorder FROM codes WHERE type=?"); $sth->execute($type); - - while (my ($code, $item, $sortorder) = $sth->fetchrow_array) { + while (my ($code, $item, $sortorder) = $sth->fetchrow_array) + { push @{$LJ::CACHE_CODES{$type}}, [ $code, $item, $sortorder ]; } - @{$LJ::CACHE_CODES{$type}} = sort { $a->[2] <=> $b->[2] } @{$LJ::CACHE_CODES{$type}}; LJ::MemCache::set($memkey, $LJ::CACHE_CODES{$type}, 60*15); } - foreach my $it (@{$LJ::CACHE_CODES{$type}}) { + foreach my $it (@{$LJ::CACHE_CODES{$type}}) + { if (ref $req->{$type} eq "HASH") { $req->{$type}->{$it->[0]} = $it->[1]; - } - elsif (ref $req->{$type} eq "ARRAY") { + } elsif (ref $req->{$type} eq "ARRAY") { push @{$req->{$type}}, { 'code' => $it->[0], 'item' => $it->[1] }; } } @@ -2219,6 +2211,7 @@ $LJ::DBIRole->flush_cache(); + %LJ::CACHE_PROP = (); %LJ::CACHE_STYLE = (); $LJ::CACHED_MOODS = 0; $LJ::CACHED_MOOD_MAX = 0; @@ -2784,7 +2777,8 @@ # des-: # returns: # </LJFUNC> -sub load_talk_props2 { +sub load_talk_props2 +{ my $db = isdb($_[0]) ? shift @_ : undef; my ($uuserid, $listref, $hashref) = @_; @@ -2795,13 +2789,11 @@ my %need; my @memkeys; - foreach (@$listref) { - my $id = $_ + 0; + my $id = $_+0; $need{$id} = 1; push @memkeys, [$userid,"talkprop:$userid:$id"]; } - return $hashref unless %need; my $mem = LJ::MemCache::get_multi(@memkeys) || {}; @@ -2820,10 +2812,7 @@ if (!$db || @LJ::MEMCACHE_SERVERS) { $u ||= LJ::load_userid($userid); - $db = @LJ::MEMCACHE_SERVERS - ? LJ::get_cluster_def_reader($u) - : LJ::get_cluster_reader($u); - + $db = @LJ::MEMCACHE_SERVERS ? LJ::get_cluster_def_reader($u) : LJ::get_cluster_reader($u); return $hashref unless $db; } @@ -2832,18 +2821,14 @@ my $sth = $db->prepare("SELECT jtalkid, tpropid, value FROM talkprop2 ". "WHERE journalid=? AND jtalkid IN ($in)"); $sth->execute($userid); - while (my ($jtalkid, $propid, $value) = $sth->fetchrow_array) { - LJ::load_props('talk') unless defined LJ::MemCache::get('CACHE_PROPID'); - my $p = LJ::MemCache::get('CACHE_PROPID')->{'talk'}->{$propid}; + my $p = $LJ::CACHE_PROPID{'talk'}->{$propid}; next unless $p; $hashref->{$jtalkid}->{$p->{'name'}} = $value; } - foreach my $id (keys %need) { LJ::MemCache::set([$userid,"talkprop:$userid:$id"], $hashref->{$id} || {}); } - return $hashref; }