@Yaschik

Многопоточность и long polling в Ruby on Rails, почему засыпает главный поток?

Есть такой код в контроллере:
def game
    ddos=Time.now
    result=nil
    r=Thread.new do
      while true
        sleep 1 //Latency-like-defend-of-DB
        result = Model.where('id!=?',1).last //Requests any model, as example
        if result
          break
        end
      end
    end
    while true
      if ddos+30<Time.now //If server not respond after 30 sec
        result='Too long'
      end
      if result
        r.kill // Kill thread
        break
      end
    end
    render json:{result:result}
  end

Гугл не дал ничего хорошего, c рельсами знаком пока что слабо.
При такой реализации основной поток засыпает, и сервер не отвечает на другие подключения.
ruby - 2.2.2, rails - 4.2.1.
Пробовал webrick и puma.
Оба работают с одним подключением, возник вопрос - я делаю что-то не так, но как сделать правильно?
  • Вопрос задан
  • 1162 просмотра
Пригласить эксперта
Ответы на вопрос 1
@raventid
Насколько я понимаю вы просто пытаетесь установить временной лимит на запрос к бд. В конфиге Rails можно установить таймаут в 30 секунд :) Смотрите здесь . Еще можно будет поймать исключение по таймауту и отрендерить код ошибки и сообщение. Не вижу особого смысла в создании треда. Кстати, еще посмотрите на то как работает ActiveRecord и ее пул, она очень многие штуки умеет делать в том числе с участием потоков.

Да, еще webrick однопоточный парень и лучше его не мучайте, для разработки установите thin.

P.S. Я попробовал немного переписать ваш метод и запустить без рельс - все работает, и в целом логично :)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы