Похоже, вы предлагаете использовать вызов binding.pry
для опроса всех дочерних потоков и приостановки их до тех пор, пока вы не завершите сеанс прослушивания. Это невозможно по техническим и практическим причинам. Классы Binding
и Thread
так не работают, и многопоточность в Ruby так не работает.
Потоки в Ruby можно приостановить, только вызвав Kernel#sleep
или Thread.stop
. (и они функционально эквивалентны). Важно отметить, что эти методы можно вызывать только в текущем потоке. Один поток не может приостанавливать другой поток. (Thread.stop
— это метод класса, а не метод экземпляра)
Давайте посмотрим, что на самом деле делает binding.pry
: объекты класса Binding инкапсулируют контекст выполнения в определенном месте кода и сохранить этот контекст для будущего использования. Поэтому, когда вы добавляете binding.pry
в свой код, вы говорите Ruby инкапсулировать контекст выполнения для текущего потока.
Это означает, что когда вы вызываете binding.pry
в основном потоке, объект Binding имеет контекст для текущего потока и может приказать себе спать, но основной класс Ruby Thread не позволяет ему сообщать другим потокам. спать.
Даже если бы он поддерживал его, это было бы странно, подвержено ошибкам и вызывало бы много головоломок. Представьте, что у вас есть такой код:
# we are in the main thread
Thread.new do
# we are in the child thread
foo = Foo.new(bar.fetch(:baz, {}))
foo.save
end
# we are in the main thread
binding.pry
Из-за того, как Ruby обрабатывает переключение контекста, если binding.pry
приказал всем дочерним потокам остановиться, то дочерний поток может остановиться В ЛЮБОМ МЕСТЕ стека вызовов, в том числе в любом месте кода для Foo.new
или .save
. Если эти потоки приостанавливаются и возобновляются в середине выполнения кода, который вы не писали, это вызовет у вас проблемы. Например, что произойдет, если соединение ActiveRecord из пула извлечено и использовано для запроса SELECT
, но поток будет переведен в спящий режим до того, как вернет соединение в пул и получит ответ? Плохие вещи. Много плохого.
Похоже, что реальным решением для вас является изменение детализации дочерних потоков. Если вы устраняете неполадки в коде чата, а другие ваши потоки создают шум, пока вы пытаетесь работать в одном потоке, временно установите для других потоков, например, более низкий уровень ведения журнала.
person
anothermh
schedule
01.06.2017