2
2
3
3
require "cases/helper"
4
4
require "models/post"
5
+ require "models/category"
5
6
require "models/comment"
6
7
require "models/other_dog"
7
8
8
9
module ActiveRecord
9
10
module WaitForAsyncTestHelper
10
11
private
11
- def wait_for_async_query ( relation , timeout : 5 )
12
- if !relation . connection . async_enabled? || relation . instance_variable_get ( :@records )
13
- return relation
14
- end
12
+ def wait_for_async_query ( connection = ActiveRecord ::Base . connection , timeout : 5 )
13
+ return unless connection . async_enabled?
15
14
16
- future_result = relation . instance_variable_get ( :@future_result )
15
+ executor = connection . pool . async_executor
17
16
( timeout * 100 ) . times do
18
- return relation unless future_result . pending?
17
+ return unless executor . scheduled_task_count > executor . completed_task_count
19
18
sleep 0.01
20
19
end
20
+
21
21
raise Timeout ::Error , "The async executor wasn't drained after #{ timeout } seconds"
22
22
end
23
23
end
@@ -27,7 +27,7 @@ class LoadAsyncTest < ActiveRecord::TestCase
27
27
28
28
self . use_transactional_tests = false
29
29
30
- fixtures :posts , :comments
30
+ fixtures :posts , :comments , :categories , :categories_posts
31
31
32
32
def test_scheduled?
33
33
deferred_posts = Post . where ( author_id : 1 ) . load_async
@@ -52,6 +52,48 @@ def test_reset
52
52
assert_not_predicate deferred_posts , :scheduled?
53
53
end
54
54
55
+ unless in_memory_db?
56
+ def test_load_async_has_many_association
57
+ post = Post . first
58
+
59
+ defered_comments = post . comments . load_async
60
+ assert_predicate defered_comments , :scheduled?
61
+
62
+ events = [ ]
63
+ callback = -> ( event ) do
64
+ events << event unless event . payload [ :name ] == "SCHEMA"
65
+ end
66
+
67
+ wait_for_async_query
68
+ ActiveSupport ::Notifications . subscribed ( callback , "sql.active_record" ) do
69
+ defered_comments . to_a
70
+ end
71
+
72
+ assert_equal [ [ "Comment Load" , true ] ] , events . map { |e | [ e . payload [ :name ] , e . payload [ :async ] ] }
73
+ assert_not_predicate post . comments , :loaded?
74
+ end
75
+
76
+ def test_load_async_has_many_through_association
77
+ post = Post . first
78
+
79
+ defered_categories = post . scategories . load_async
80
+ assert_predicate defered_categories , :scheduled?
81
+
82
+ events = [ ]
83
+ callback = -> ( event ) do
84
+ events << event unless event . payload [ :name ] == "SCHEMA"
85
+ end
86
+
87
+ wait_for_async_query
88
+ ActiveSupport ::Notifications . subscribed ( callback , "sql.active_record" ) do
89
+ defered_categories . to_a
90
+ end
91
+
92
+ assert_equal [ [ "Category Load" , true ] ] , events . map { |e | [ e . payload [ :name ] , e . payload [ :async ] ] }
93
+ assert_not_predicate post . scategories , :loaded?
94
+ end
95
+ end
96
+
55
97
def test_notification_forwarding
56
98
expected_records = Post . where ( author_id : 1 ) . to_a
57
99
@@ -66,7 +108,8 @@ def test_notification_forwarding
66
108
end
67
109
end
68
110
69
- deferred_posts = wait_for_async_query ( Post . where ( author_id : 1 ) . load_async )
111
+ deferred_posts = Post . where ( author_id : 1 ) . load_async
112
+ wait_for_async_query
70
113
71
114
assert_equal expected_records , deferred_posts . to_a
72
115
assert_equal Post . connection . supports_concurrent_connections? , status [ :async ]
@@ -92,7 +135,8 @@ def test_simple_query
92
135
end
93
136
end
94
137
95
- deferred_posts = wait_for_async_query ( Post . where ( author_id : 1 ) . load_async )
138
+ deferred_posts = Post . where ( author_id : 1 ) . load_async
139
+ wait_for_async_query
96
140
97
141
assert_equal expected_records , deferred_posts . to_a
98
142
assert_equal Post . connection . supports_concurrent_connections? , status [ :async ]
@@ -130,7 +174,8 @@ def test_eager_loading_query
130
174
end
131
175
end
132
176
133
- deferred_posts = wait_for_async_query ( Post . where ( author_id : 1 ) . eager_load ( :comments ) . load_async )
177
+ deferred_posts = Post . where ( author_id : 1 ) . eager_load ( :comments ) . load_async
178
+ wait_for_async_query
134
179
135
180
if in_memory_db?
136
181
assert_not_predicate deferred_posts , :scheduled?
@@ -355,7 +400,8 @@ def test_simple_query
355
400
end
356
401
end
357
402
358
- deferred_posts = wait_for_async_query ( Post . where ( author_id : 1 ) . load_async )
403
+ deferred_posts = Post . where ( author_id : 1 ) . load_async
404
+ wait_for_async_query
359
405
360
406
assert_equal expected_records , deferred_posts . to_a
361
407
assert_equal Post . connection . supports_concurrent_connections? , status [ :async ]
@@ -388,7 +434,8 @@ def test_eager_loading_query
388
434
end
389
435
end
390
436
391
- deferred_posts = wait_for_async_query ( Post . where ( author_id : 1 ) . eager_load ( :comments ) . load_async )
437
+ deferred_posts = Post . where ( author_id : 1 ) . eager_load ( :comments ) . load_async
438
+ wait_for_async_query
392
439
393
440
assert_predicate deferred_posts , :scheduled?
394
441
@@ -497,8 +544,8 @@ def test_simple_query
497
544
deferred_posts = Post . where ( author_id : 1 ) . load_async
498
545
deferred_dogs = OtherDog . where ( id : 1 ) . load_async
499
546
500
- wait_for_async_query ( deferred_posts )
501
- wait_for_async_query ( deferred_dogs )
547
+ wait_for_async_query
548
+ wait_for_async_query
502
549
503
550
assert_equal expected_records , deferred_posts . to_a
504
551
assert_equal expected_dogs , deferred_dogs . to_a
0 commit comments