Spec-Zone.ru › Ruby on Rails 6.1

модуль ActionController::Streaming

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

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

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

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

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

Streaming можно легко добавить в шаблон, достаточно передать параметр :stream.

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

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

Streaming может быть избыточным для легких действий, таких как 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 работает только с шаблонами. Rendering :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. Пожалуйста, ознакомьтесь с документацией для получения дополнительной информации: bogomips.org/unicorn/Unicorn/Configurator.html#method-i-listen

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

Passenger

Ожидается описание.

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

Spec-Zone.ru

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