Mike Tougeron
Well-known member
I know this is definitely an edge case but I came across it last night and it took me a few hours to research the problem so thought I should report it anyway.
IGN has an extremely large thread (http://www.ign.com/boards/threads/»...to-feed-some-*******-fish-thread-««.77575142/) with 152,798 messages that was imported from our old boards system. Because of the way that XenForo handles the addition of a new message the queries timeout and the new message is not saved.
I believe, but I'm not positive, that it is because of the following flow:
Because it's a new message, XenForo_DataWriter_DiscussionMessage::_postSave() calls XenForo_DataWriter_DiscussionMessage::_updateDiscussionPostSave() which then calls XenForo_DataWriter_Discussion::updateCountersAfterMessageSave() which is acting on the thread's datawriter. So later in in XenForo_DataWriter_DiscussionMessage::_postSave() it calls XenForo_DataWriter_DiscussionMessage::_saveDiscussionDataWriter().
Eventually it ends up calling XenForo_DataWriter_Discussion::_postSave(). This method does $messages = $this->_getMessagesInDiscussionSimple(); and that gets all the messages in the thread. In the case of this topic for IGN that means it tries to load all 152,798 messages from the db. With a warm db cache this query takes about 2 minutes to execute. If the query is executed without the sort and the sorting is done in PHP it only takes about a minute (though that is still unacceptably long).
I'm not sure what the best solution for this is, but for now I'm going to lock that topic and put a cap in for 10k messages per thread.
IGN has an extremely large thread (http://www.ign.com/boards/threads/»...to-feed-some-*******-fish-thread-««.77575142/) with 152,798 messages that was imported from our old boards system. Because of the way that XenForo handles the addition of a new message the queries timeout and the new message is not saved.
I believe, but I'm not positive, that it is because of the following flow:
Because it's a new message, XenForo_DataWriter_DiscussionMessage::_postSave() calls XenForo_DataWriter_DiscussionMessage::_updateDiscussionPostSave() which then calls XenForo_DataWriter_Discussion::updateCountersAfterMessageSave() which is acting on the thread's datawriter. So later in in XenForo_DataWriter_DiscussionMessage::_postSave() it calls XenForo_DataWriter_DiscussionMessage::_saveDiscussionDataWriter().
Eventually it ends up calling XenForo_DataWriter_Discussion::_postSave(). This method does $messages = $this->_getMessagesInDiscussionSimple(); and that gets all the messages in the thread. In the case of this topic for IGN that means it tries to load all 152,798 messages from the db. With a warm db cache this query takes about 2 minutes to execute. If the query is executed without the sort and the sorting is done in PHP it only takes about a minute (though that is still unacceptably long).
I'm not sure what the best solution for this is, but for now I'm going to lock that topic and put a cap in for 10k messages per thread.