Deadlock race when calling ScheduledTask#reschedule
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 35/100
Hướng nghiên cứu
Start with lib/concurrent-ruby/concurrent/scheduled_task.rb, especially reschedule, ns_reschedule, and schedule_time, then inspect lib/concurrent-ruby/concurrent/executor/timer_set.rb and its process_tasks and remove_task paths. Reproduce the lock-ordering race described in the issue and use the cited priority queue stack to observe it. Done means the reschedule and timer-processing paths no longer deadlock.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
I believe I've found a deadlock in ScheduledTask / TimerSet, which appears to be present in both old (1.2.3) and current (1.3.6) concurrent-ruby.
If one creates a ScheduledTask, and calls reschedule() on it from the main thread on it right as the TimerSet background thread wakes up to run the #process_tasks loop, a deadlock can occur.
Thread 1: ScheduledTask#reschedule is called explicitly:
- locks ScheduledTask.synchronize (scheduled_task.rb:265)
- calls ns_reschedule, which in turn calls
TimerSet#remove_task - which tries to lock TimerSet.synchronize (timer_set.rb:117)
Thread 2: TimerSet#process_tasks runs auto in the background:
- Calls
task = synchronize { @queue.pop }(timer_set.rb:167) - This locks TImerSet.synchronize
- @queue.pop tries to pop the soonest work item, which results in invoking
ScheduledTask#schedule_timeto sort/compare queue items - which tries to lock ScheduledTask.synchronize before accessing @time (scheduled_task.rb:207)
Below I show two threads which are deadlocked in this fashion, showing the issue, and where each thread grabs each lock. One thread is a puma request thread, which ends up calling ScheduledTask#reschedule.
# put_metric_data request #2 (TID-dh2ik puma srv tp 005)
#
# Lock Conditions:
# - TimerSet: trying to lock
# - ScheduledTask: locked
#
[171733] Thread: TID-dh2ik puma srv tp 005
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:48:in 'synchronize'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:48:in 'synchronize'
#### <---- TRY TO LOCK TimerSet.synchronize ####
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/timer_set.rb:116:in 'remove_task'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/scheduled_task.rb:328:in 'ns_reschedule'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/scheduled_task.rb:265:in 'block in reschedule'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:46:in 'synchronize'
#### <---- LOCK ScheduledTask.synchronize ####
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/scheduled_task.rb:265:in 'reschedule'
# SNIP, long puma/rails request backtrace which doesn't use concurrent
# concurrent-ruby scheduled_task (TID-4jpio worker-1)
#
# Lock Conditions:
# - TimerSet: locked
# - ScheduledTask: trying to lock
#
[171733] Thread: TID-4jpio worker-1
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:48:in 'synchronize'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:48:in 'synchronize'
#### <---- TRY TO LOCK ScheduledTask.synchronize ####
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/scheduled_task.rb:207:in 'schedule_time'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/scheduled_task.rb:214:in '<=>'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb:120:in 'ordered?'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb:133:in 'sink'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb:70:in 'pop'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/timer_set.rb:164:in 'block (2 levels) in process_tasks'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:48:in 'block in synchronize'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:48:in 'synchronize'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:48:in 'synchronize'
#### <---- LOCK TimerSet.synchronize ####
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/timer_set.rb:164:in 'block in process_tasks'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/timer_set.rb:144:in 'loop'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/timer_set.rb:144:in 'process_tasks'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:359:in 'run_task'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:350:in 'block (3 levels) in create_worker'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:341:in 'loop'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:341:in 'block (2 levels) in create_worker'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:340:in 'catch'
concurrent-ruby-1.2.3/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:340:in 'block in create_worker'
- Ngôn ngữ chính
- Ruby
- Star
- 5.8k
- Fork
- 420
- Merge trung bình
- 20 giờ 45 phút
- Pull request đã merge (30 ngày)
- 4
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của ruby-concurrency/concurrent-ruby
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
ruby-concurrency/concurrent-ruby#1118 ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
ruby-concurrency/concurrent-ruby#1095 · 8 bình luận ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
ruby-concurrency/concurrent-ruby#1093 · 3 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 45/100
ruby-concurrency/concurrent-ruby#1091 ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
ruby-concurrency/concurrent-ruby#1072 · 1 reaction ·
Tất cả issue của ruby-concurrency/concurrent-ruby
Issue tương tự
-
バグ
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 92/100
-
Version bump for OpenVox 9 Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
voxpupuli/puppet-epel#186 · 1 bình luận ·
-
external_created_at is no longer used for the message timestamp since the new message UI (v4.4.0) Đang mởBug Frontend
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
TheOdinProject/curriculum#31402 · 1 bình luận ·
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100