Поток Ruby умирает после перенаправления

#ruby #multithreading

#ruby #многопоточность

Вопрос:

я запускаю поток в своем контроллере и хочу перенаправить пользователя сразу после этого.

 class Profile::GeneralController < ProfileController
    def update
       startTheThread(profile)
       #sleep(5)
       redirect_to 'selection_controller'
    end
end

class ProfileController < ApplicationController
    def startTheThread(profile = nil)
        $collector_threads[current_user.id][sector] = Thread.new {
            Thread.current['collecting_status'] = { a: 1, c: 0, c_id: -1, r: false }            
            start_threaded_collector(sector)
        }
    end
end
  

Когда я говорю контроллеру перейти в режим ожидания, скажем, на 5 секунд, поток завершается так, как и предполагалось.

Поток отключается, как только пользователь переходит на другую страницу — почему это так и как я могу поддерживать потоки на контроллерах.

Комментарии:

1. Вы запускаете это на многопоточном сервере? (не webrick)

2. я использую «тонкий» как веб-сервер

3. Вы делаете что-то очень неправильное. Если вам нужна какая-то асинхронная обработка, вам следует использовать ActiveJob, Sidekiq или другую очередь заданий.

4. Если вы действительно хотите получить этот путь, попробуйте puma. thin использует eventmachine. В часто задаваемых вопросах Eventmachines говорится, что могут возникнуть проблемы с другими потоками. Этот блог- блог. arkency.com/2013/06/implementing-worker-threads-in-rails это должно дать вам несколько подсказок.

Ответ №1:

Я здесь с @meagar, это вызывает серьезные проблемы. Предположим, что ваш процесс будет остановлен после завершения выполнения веб-запроса, поскольку это происходит в некоторых менеджерах процессов Ruby on Rails, когда они удаляют лишние экземпляры.

Совместное использование данных между экземплярами контроллера также следует считать невозможным, если вы каким-либо образом не сохраняете данные: базу данных, сеанс, файлы cookie или аргументы через GET или POST .

В типичной системе у вас будет N процессов Ruby на M машинах, и процессы будут запускаться и останавливаться произвольно, без предупреждения, если они не обрабатывают активно какие-либо запросы. Невозможно надежно обмениваться данными между ними без какого-либо внешнего IPC.

Вероятно, вам нужен фоновый серверный процесс, к которому эти контроллеры могут обращаться за любой информацией, которая им может понадобиться, или процесс, который может сбрасывать данные в базу данных или службу, такую как Redis, где их можно получить.

Способ, которым вы могли бы это спроектировать, — это поместить задание в очередь Redis, создать другой процесс, который следит за этой очередью на предмет выполнения работы, извлекает задание и обрабатывает его. Это легко сделать с BLPOP помощью команды в Redis, где ваш поток заблокирует ожидание работы, а затем немедленно продолжит, когда будет что-то делать.