Spec-Zone.ru › Ruby on Rails 5.1

модуль ActionController::Streaming

Позволяет отображать представления на клиенте по мере их рендеринга.

По умолчанию Rails отображает представления, сначала рендеринга шаблон, а затем макет. Ответ отправляется клиенту после того, как весь шаблон отрендерен, все запросы выполнены, и обработан макет.

Потоковая передача изменяет порядок рендеринга, сначала рендеринга макет и потоковой передачи каждой части макета по мере обработки. Это позволяет быстро отправлять заголовок HTML (который обычно находится в макете) клиенту, что позволяет загружать JavaScript и таблицы стилей раньше, чем обычно.

Этот подход был представлен в Rails 3.1 и все еще совершенствуется. Некоторые промежуточные программные обеспечения Rack могут не работать, и вам нужно быть осторожным при потоковой передаче. Эти моменты будут скоро решены.

Для использования потоковой передачи вам потребуется версия Ruby, поддерживающая волокна (волокна поддерживаются с версии 1.9.2 основного реализация Ruby).

Потоковая передача может быть легко добавлена в шаблон, все, что вам нужно сделать, это передать параметр :stream.

class PostsController
  def index
    @posts = Post.all
    render stream: true
  end
end

Когда использовать потоковую передачу

Потоковая передача может быть избыточной для лёгких действий, таких как new или edit. Настоящая польза потоковой передачи заключается в сложных действиях, которые, например, выполняют много запросов к базе данных.

В таких действиях вы хотите отложить выполнение запросов как можно дальше. Например, представьте следующее dashboard действие:

def dashboard
  @posts = Post.all
  @pages = Page.all
  @articles = Article.all
end

Большинство запросов здесь выполняется в контроллере. Чтобы воспользоваться преимуществами потоковой передачи, вы хотите переписать его как:

def dashboard
  # Allow lazy execution of the queries
  @posts = Post.all
  @pages = Page.all
  @articles = Article.all
  render stream: true
end

Обратите внимание, что :stream работает только с шаблонами. Отображение :json или :xml с :stream не будет работать.

Взаимодействие между макетом и шаблоном

При потоковой передаче рендеринг происходит сверху вниз, а не изнутри наружу. Rails начинает с макета, а шаблон рендерится позже, когда достигается его yield.

Это означает, что если ваше приложение в настоящее время полагается на переменные экземпляра, установленные в шаблоне, для использования в макете, они не будут работать после перехода на потоковую передачу. Правильный способ взаимодействия между макетом и шаблоном, независимо от того, используете вы потоковую передачу или нет, — использовать content_for, provide и yield.

Рассмотрим простой пример, где макет ожидает, что шаблон укажет, какой заголовок использовать:

<html>
  <head><title><%= yield :title %></title></head>
  <body><%= yield %></body>
</html>

Вы бы использовали content_for в шаблоне, чтобы указать заголовок:

<%= content_for :title, "Main" %>
Hello

И конечным результатом будет:

<html>
  <head><title>Main</title></head>
  <body>Hello</body>
</html>

Однако, если content_for вызывается несколько раз, конечный результат будет содержать все вызовы, соединённые вместе. Например, если у нас есть следующий шаблон:

<%= content_for :title, "Main" %>
Hello
<%= content_for :title, " page" %>

Конечным результатом будет:

<html>
  <head><title>Main page</title></head>
  <body>Hello</body>
</html>

Это означает, что если у вас yield :title в вашем макете, и вы хотите использовать потоковую передачу, вам придется рендерить весь шаблон (и, возможно, выполнить все запросы) перед потоковой передачей заголовка и всех ресурсов, что убивает смысл потоковой передачи. Для этого можно использовать вспомогательную функцию provide, которая делает то же, что и content_for, но сообщает макету прекратить поиск других элементов и продолжить рендеринг.

Например, шаблон выше, использующий provide будет:

<%= provide :title, "Main" %>
Hello
<%= content_for :title, " page" %>

Что даёт:

<html>
  <head><title>Main</title></head>
  <body>Hello</body>
</html>

Таким образом, при использовании потоковой передачи необходимо правильно проверить ваши шаблоны и выбрать, когда использовать provide и content_for.

Заголовки, куки, сессия и сообщения

При потоковой передаче HTTP-заголовки отправляются клиенту непосредственно перед отображением первой строки. Это означает, что изменение заголовков, куки, сессии или сообщений после начала рендеринга шаблона не будет передано клиенту.

Промежуточные программы

Промежуточные программы, которые должны манипулировать телом, не будут работать с потоковой передачей. Вам следует отключать эти промежуточные программы при использовании потоковой передачи в разработке или производстве. Например, Rack::Bug не будет работать при потоковой передаче, так как ему нужно вставлять содержимое в тело HTML.

Также Rack::Cache не будет работать с потоковой передачей, так как пока не поддерживает потоковую передачу тела. При потоковой передаче Cache-Control автоматически устанавливается в «no-cache».

Ошибки

При потоковой передаче обработка исключений становится немного сложнее. Это происходит, потому что часть шаблона уже была отрендерена и передана клиенту, что делает невозможным отображение полной страницы с ошибкой.

В настоящее время, когда в разработке или производстве происходит исключение, Rails автоматически отправляет клиенту:

"><script>window.location = "/500.html"</script></html>

Первые два символа («>») необходимы, если исключение произойдёт во время рендеринга атрибутов для данного тега. Вы можете проверить фактическую причину исключения в своём логере.

Поддержка веб-сервера

Не все веб-серверы поддерживают потоковую передачу «из коробки». Вам нужно проверить инструкции для каждого из них.

Unicorn

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

# unicorn.config.rb
listen 3000, tcp_nopush: false

И использовать его при инициализации:

unicorn_rails --config-file unicorn.config.rb

Также можно настроить другие параметры, такие как :tcp_nodelay. Пожалуйста, ознакомьтесь с документацией для получения дополнительной информации: unicorn.bogomips.org/Unicorn/Configurator.html#method-i-listen

Если вы используете Unicorn с NGINX, вам может потребоваться настроить NGINX. Потоковая передача должна работать «из коробки» с Rainbows.

Passenger

Описано не будет.

© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API