mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-24 23:06:50 +00:00
Merge branch 'fix_thread_safety_bug' into 0-10-stable
This commit is contained in:
commit
09264da273
@ -347,7 +347,7 @@ module ActiveModel
|
|||||||
return Enumerator.new {} unless object
|
return Enumerator.new {} unless object
|
||||||
|
|
||||||
Enumerator.new do |y|
|
Enumerator.new do |y|
|
||||||
self.class._reflections.each do |key, reflection|
|
(self.instance_reflections ||= self.class._reflections.deep_dup).each do |key, reflection|
|
||||||
next if reflection.excluded?(self)
|
next if reflection.excluded?(self)
|
||||||
next unless include_directive.key?(key)
|
next unless include_directive.key?(key)
|
||||||
|
|
||||||
@ -411,6 +411,6 @@ module ActiveModel
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
attr_accessor :instance_options
|
attr_accessor :instance_options, :instance_reflections
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -151,6 +151,9 @@ module ActiveModel
|
|||||||
# @yield [ActiveModel::Serializer]
|
# @yield [ActiveModel::Serializer]
|
||||||
# @return [:nil, associated resource or resource collection]
|
# @return [:nil, associated resource or resource collection]
|
||||||
def value(serializer, include_slice)
|
def value(serializer, include_slice)
|
||||||
|
# NOTE(BF): This method isn't thread-safe because the _reflections class attribute is not thread-safe
|
||||||
|
# Therefore, when we build associations from reflections, we dup the entire reflection instance.
|
||||||
|
# Better solutions much appreciated!
|
||||||
@object = serializer.object
|
@object = serializer.object
|
||||||
@scope = serializer.scope
|
@scope = serializer.scope
|
||||||
|
|
||||||
|
|||||||
@ -423,5 +423,57 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
# rubocop:enable Metrics/AbcSize
|
# rubocop:enable Metrics/AbcSize
|
||||||
end
|
end
|
||||||
|
class ThreadedReflectionTest < ActiveSupport::TestCase
|
||||||
|
class Post < ::Model
|
||||||
|
attributes :id, :title, :body
|
||||||
|
associations :comments
|
||||||
|
end
|
||||||
|
class Comment < ::Model
|
||||||
|
attributes :id, :body
|
||||||
|
associations :post
|
||||||
|
end
|
||||||
|
class CommentSerializer < ActiveModel::Serializer
|
||||||
|
type 'comment'
|
||||||
|
attributes :id, :body
|
||||||
|
has_one :post
|
||||||
|
end
|
||||||
|
class PostSerializer < ActiveModel::Serializer
|
||||||
|
type 'post'
|
||||||
|
attributes :id, :title, :body
|
||||||
|
has_many :comments, serializer: CommentSerializer do
|
||||||
|
sleep 0.1
|
||||||
|
object.comments
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# per https://github.com/rails-api/active_model_serializers/issues/2270
|
||||||
|
def test_concurrent_serialization
|
||||||
|
post1 = Post.new(id: 1, title: 'Post 1 Title', body: 'Post 1 Body')
|
||||||
|
post1.comments = [Comment.new(id: 1, body: 'Comment on Post 1', post: post1)]
|
||||||
|
post2 = Post.new(id: 2, title: 'Post 2 Title', body: 'Post 2 Body')
|
||||||
|
post2.comments = [Comment.new(id: 2, body: 'Comment on Post 2', post: post2)]
|
||||||
|
serialized_posts = {
|
||||||
|
first: Set.new,
|
||||||
|
second: Set.new
|
||||||
|
}
|
||||||
|
t1 = Thread.new do
|
||||||
|
10.times do
|
||||||
|
serialized_posts[:first] << PostSerializer.new(post1, {}).to_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
t2 = Thread.new do
|
||||||
|
10.times do
|
||||||
|
serialized_posts[:second] << PostSerializer.new(post2, {}).to_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
t1.join
|
||||||
|
t2.join
|
||||||
|
expected_first_post_serialization = '{"id":1,"title":"Post 1 Title","body":"Post 1 Body","comments":[{"id":1,"body":"Comment on Post 1"}]}'
|
||||||
|
expected_second_post_serialization = '{"id":2,"title":"Post 2 Title","body":"Post 2 Body","comments":[{"id":2,"body":"Comment on Post 2"}]}'
|
||||||
|
|
||||||
|
assert_equal [expected_second_post_serialization], serialized_posts[:second].to_a
|
||||||
|
assert_equal [expected_first_post_serialization], serialized_posts[:first].to_a
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user