FIX: Deadlock when topic with auto close topic timers exceeds auto_close_topics_post_count.

This commit is contained in:
Guo Xiang Tan 2018-04-23 13:32:08 +08:00
parent 6a0aeae91b
commit c148500d51
2 changed files with 108 additions and 36 deletions

View File

@ -291,22 +291,34 @@ class PostCreator
end end
def auto_close def auto_close
if @post.topic.private_message? && topic = @post.topic
!@post.topic.closed && is_private_message = topic.private_message?
topic_posts_count = @post.topic.posts_count
if is_private_message &&
!topic.closed &&
SiteSetting.auto_close_messages_post_count > 0 && SiteSetting.auto_close_messages_post_count > 0 &&
SiteSetting.auto_close_messages_post_count <= @post.topic.posts_count SiteSetting.auto_close_messages_post_count <= topic_posts_count
@post.topic.update_status(:closed, true, Discourse.system_user, @post.topic.update_status(
message: I18n.t('topic_statuses.autoclosed_message_max_posts', count: SiteSetting.auto_close_messages_post_count)) :closed, true, Discourse.system_user,
message: I18n.t(
elsif !@post.topic.private_message? && 'topic_statuses.autoclosed_message_max_posts',
!@post.topic.closed && count: SiteSetting.auto_close_messages_post_count
)
)
elsif !is_private_message &&
!topic.closed &&
SiteSetting.auto_close_topics_post_count > 0 && SiteSetting.auto_close_topics_post_count > 0 &&
SiteSetting.auto_close_topics_post_count <= @post.topic.posts_count SiteSetting.auto_close_topics_post_count <= topic_posts_count
@post.topic.update_status(:closed, true, Discourse.system_user,
message: I18n.t('topic_statuses.autoclosed_topic_max_posts', count: SiteSetting.auto_close_topics_post_count))
topic.update_status(
:closed, true, Discourse.system_user,
message: I18n.t(
'topic_statuses.autoclosed_topic_max_posts',
count: SiteSetting.auto_close_topics_post_count
)
)
end end
end end
@ -405,6 +417,9 @@ class PostCreator
end end
def update_topic_auto_close def update_topic_auto_close
if @topic.closed?
@topic.delete_topic_timer(TopicTimer.types[:close])
else
topic_timer = @topic.public_topic_timer topic_timer = @topic.public_topic_timer
if topic_timer && if topic_timer &&
@ -417,6 +432,7 @@ class PostCreator
) )
end end
end end
end
def setup_post def setup_post
@opts[:raw] = TextCleaner.normalize_whitespaces(@opts[:raw] || '').gsub(/\s+\z/, "") @opts[:raw] = TextCleaner.normalize_whitespaces(@opts[:raw] || '').gsub(/\s+\z/, "")

View File

@ -306,23 +306,64 @@ describe PostCreator do
expect(topic_status_update.created_at).to be_within(1.second).of(Time.zone.now) expect(topic_status_update.created_at).to be_within(1.second).of(Time.zone.now)
end end
it "updates topic's auto close date when it's based on last post" do describe "topic's auto close based on last post" do
freeze_time let(:topic_timer) do
topic = Fabricate(:topic_timer, Fabricate(:topic_timer,
based_on_last_post: true, based_on_last_post: true,
execute_at: Time.zone.now - 12.hours, execute_at: Time.zone.now - 12.hours,
created_at: Time.zone.now - 24.hours created_at: Time.zone.now - 24.hours
).topic )
Fabricate(:post, topic: topic)
PostCreator.new(topic.user, topic_id: topic.id, raw: "this is a second post").create
topic_status_update = TopicTimer.last
expect(topic_status_update.execute_at).to be_within(1.second).of(Time.zone.now + 12.hours)
expect(topic_status_update.created_at).to be_within(1.second).of(Time.zone.now)
end end
let(:topic) { topic_timer.topic }
let(:post) do
Fabricate(:post, topic: topic)
end
it "updates topic's auto close date" do
freeze_time
post
PostCreator.new(
topic.user,
topic_id: topic.id,
raw: "this is a second post"
).create
topic_timer.reload
expect(topic_timer.execute_at).to eq(Time.zone.now + 12.hours)
expect(topic_timer.created_at).to eq(Time.zone.now)
end
describe "when auto_close_topics_post_count has been reached" do
before do
SiteSetting.auto_close_topics_post_count = 2
end
it "closes the topic and deletes the topic timer" do
freeze_time
post
PostCreator.new(
topic.user,
topic_id: topic.id,
raw: "this is a second post"
).create
topic.reload
expect(topic.posts.last.raw).to eq(I18n.t(
'topic_statuses.autoclosed_topic_max_posts',
count: SiteSetting.auto_close_topics_post_count
))
expect(topic.closed).to eq(true)
expect(topic_timer.reload.deleted_at).to eq(Time.zone.now)
end
end
end
end end
context "tags" do context "tags" do
@ -742,9 +783,17 @@ describe PostCreator do
post1 = create_post(archetype: Archetype.private_message, post1 = create_post(archetype: Archetype.private_message,
target_usernames: [admin.username]) target_usernames: [admin.username])
_post2 = create_post(user: post1.user, topic_id: post1.topic_id) expect do
create_post(user: post1.user, topic_id: post1.topic_id)
end.to change { Post.count }.by(2)
post1.topic.reload post1.topic.reload
expect(post1.topic.posts.last.raw).to eq(I18n.t(
'topic_statuses.autoclosed_message_max_posts',
count: SiteSetting.auto_close_messages_post_count
))
expect(post1.topic.closed).to eq(true) expect(post1.topic.closed).to eq(true)
end end
@ -752,11 +801,18 @@ describe PostCreator do
SiteSetting.auto_close_topics_post_count = 2 SiteSetting.auto_close_topics_post_count = 2
post1 = create_post post1 = create_post
_post2 = create_post(user: post1.user, topic_id: post1.topic_id)
expect do
create_post(user: post1.user, topic_id: post1.topic_id)
end.to change { Post.count }.by(2)
post1.topic.reload post1.topic.reload
expect(post1.topic.posts_count).to eq(3) expect(post1.topic.posts.last.raw).to eq(I18n.t(
'topic_statuses.autoclosed_topic_max_posts',
count: SiteSetting.auto_close_topics_post_count
))
expect(post1.topic.closed).to eq(true) expect(post1.topic.closed).to eq(true)
end end
end end