From ec24f283dd6f1371125c042529f571645a5f13fa Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 2 Apr 2010 15:45:03 -0700 Subject: [PATCH] Don't save duplicate messages into a user's packed inbox. We've already got the packed box loaded at insert time, so we can simply unpack it and check before doing the update query. Should help with dupes that come in when inbox distrib jobs die and get restarted, etc. Conflicts: classes/Inbox.php Looks like this was implemented on master recently and not copied up to testing. Merging to my version on testing as I've added some doc comments and extracted a couple functions for future ease of use. --- classes/Inbox.php | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/classes/Inbox.php b/classes/Inbox.php index 0d807946d5..2533210b73 100644 --- a/classes/Inbox.php +++ b/classes/Inbox.php @@ -96,12 +96,23 @@ class Inbox extends Memcached_DataObject $inbox = new Inbox(); $inbox->user_id = $user_id; - $inbox->notice_ids = call_user_func_array('pack', array_merge(array('N*'), $ids)); + $inbox->pack($ids); $inbox->fake = true; return $inbox; } + /** + * Append the given notice to the given user's inbox. + * Caching updates are managed for the inbox itself. + * + * If the notice is already in this inbox, the second + * add will be silently dropped. + * + * @param int @user_id + * @param int $notice_id + * @return boolean success + */ static function insertNotice($user_id, $notice_id) { $inbox = DB_DataObject::staticGet('inbox', 'user_id', $user_id); @@ -114,13 +125,10 @@ class Inbox extends Memcached_DataObject return false; } - $ids = unpack('N*', $inbox->notice_ids); - - // bulk inserts sometimes fail and get restarted. - // Skip if this one has been inserted before. - - if (in_array($notice_id, $ids)) { - // effectively successful + $ids = $inbox->unpack(); + if (in_array(intval($notice_id), $ids)) { + // Already in there, we probably re-ran some inbox adds + // due to an error. Skip the dupe silently. return true; } @@ -160,7 +168,7 @@ class Inbox extends Memcached_DataObject } } - $ids = unpack('N*', $inbox->notice_ids); + $ids = $inbox->unpack(); if (!empty($since_id)) { $newids = array(); @@ -239,4 +247,21 @@ class Inbox extends Memcached_DataObject } return new ArrayWrapper($items); } + + /** + * Saves a list of integer notice_ids into a packed blob in this object. + * @param array $ids list of integer notice_ids + */ + protected function pack(array $ids) + { + $this->notice_ids = call_user_func_array('pack', array_merge(array('N*'), $ids)); + } + + /** + * @return array of integer notice_ids + */ + protected function unpack() + { + return unpack('N*', $this->notice_ids); + } }