mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 09:12:45 +08:00
FIX: eliminate race condition creating posts
FIX: correct message bus posting
This commit is contained in:
parent
e7e70d14da
commit
9147af1d62
|
@ -1,6 +1,10 @@
|
|||
# Cross-process locking using Redis.
|
||||
class DistributedMutex
|
||||
|
||||
def self.synchronize(key, redis=nil, &blk)
|
||||
self.new(key, redis).synchronize(&blk)
|
||||
end
|
||||
|
||||
def initialize(key, redis=nil)
|
||||
@key = key
|
||||
@redis = redis || $redis
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
require_dependency 'rate_limiter'
|
||||
require_dependency 'topic_creator'
|
||||
require_dependency 'post_jobs_enqueuer'
|
||||
require_dependency 'distributed_mutex'
|
||||
|
||||
class PostCreator
|
||||
|
||||
|
@ -54,7 +55,7 @@ class PostCreator
|
|||
@topic = nil
|
||||
@post = nil
|
||||
|
||||
Post.transaction do
|
||||
transaction do
|
||||
setup_topic
|
||||
setup_post
|
||||
rollback_if_host_spam_detected
|
||||
|
@ -66,21 +67,24 @@ class PostCreator
|
|||
update_user_counts
|
||||
create_embedded_topic
|
||||
|
||||
publish
|
||||
ensure_in_allowed_users if guardian.is_staff?
|
||||
@post.advance_draft_sequence
|
||||
@post.save_reply_relationships
|
||||
end
|
||||
|
||||
if @post
|
||||
if @post && @post.errors.empty?
|
||||
publish
|
||||
PostAlerter.post_created(@post) unless @opts[:import_mode]
|
||||
|
||||
handle_spam unless @opts[:import_mode]
|
||||
track_latest_on_category
|
||||
enqueue_jobs
|
||||
BadgeGranter.queue_badge_grant(Badge::Trigger::PostRevision, post: @post)
|
||||
end
|
||||
|
||||
if @post && (@post.errors.present? || @spam)
|
||||
handle_spam unless @opts[:import_mode]
|
||||
end
|
||||
|
||||
@post
|
||||
end
|
||||
|
||||
|
@ -111,6 +115,18 @@ class PostCreator
|
|||
|
||||
protected
|
||||
|
||||
def transaction(&blk)
|
||||
Post.transaction do
|
||||
if new_topic?
|
||||
blk.call
|
||||
else
|
||||
# we need to ensure post_number is monotonically increasing with no gaps
|
||||
# so we serialize creation to avoid needing rollbacks
|
||||
DistributedMutex.synchronize("topic_id_#{@opts[:topic_id]}", &blk)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# You can supply an `embed_url` for a post to set up the embedded relationship.
|
||||
# This is used by the wp-discourse plugin to associate a remote post with a
|
||||
# discourse post.
|
||||
|
|
Loading…
Reference in New Issue
Block a user