Skip to content

Commit 2faa51c

Browse files
DangerDawsonflash-gordon
authored andcommitted
Optimise the repository relations reader
1 parent 7ebd00d commit 2faa51c

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

repository/lib/rom/repository/relation_reader.rb

+35-8
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,53 @@ module ROM
44
class Repository
55
# @api private
66
class RelationReader < ::Module
7+
extend ::Dry::Core::ClassAttributes
8+
79
# @api private
810
attr_reader :klass
911

1012
# @api private
1113
attr_reader :relations
1214

15+
defines :relation_readers
16+
17+
defines :mutex
18+
mutex(Mutex.new)
19+
20+
defines :relation_cache
21+
relation_cache(Concurrent::Hash.new)
22+
1323
module InstanceMethods
1424
# @api private
1525
def set_relation(name) # rubocop:disable Naming/AccessorMethodName
1626
container
1727
.relations[name]
18-
.with(auto_struct: auto_struct)
19-
.struct_namespace(struct_namespace)
28+
.with(auto_struct: auto_struct, struct_namespace: struct_namespace)
29+
end
30+
31+
def relation_reader(name, relation_cache)
32+
key = [name, auto_struct, struct_namespace]
33+
relation_cache[key] ||= set_relation(name)
2034
end
2135
end
2236

37+
# @api private
38+
def mutex
39+
ROM::Repository::RelationReader.mutex
40+
end
41+
2342
# @api private
2443
def initialize(klass, relations)
2544
super()
26-
@klass = klass
2745
@relations = relations
28-
define_readers!
46+
mutex.synchronize do
47+
unless self.class.relation_readers
48+
self.class.relation_readers(
49+
build_relation_readers(relations, self.class.relation_cache)
50+
)
51+
end
52+
end
53+
klass.include self.class.relation_readers
2954
end
3055

3156
# @api private
@@ -37,10 +62,12 @@ def included(klass)
3762
private
3863

3964
# @api private
40-
def define_readers!
41-
relations.each do |name|
42-
define_method(name) do
43-
@relations[name] ||= set_relation(name)
65+
def build_relation_readers(relations, relation_cache)
66+
Module.new do
67+
relations.each do |name|
68+
define_method(name) do
69+
relation_reader(name, relation_cache)
70+
end
4471
end
4572
end
4673
end

0 commit comments

Comments
 (0)