POD2-RU-PSGI

 view release on metacpan or  search on metacpan

lib/POD2/RU/PSGI.pod  view on Meta::CPAN

сервера, основанного на CGI (или на чём-то похожем).


=item *

C<psgi.nonblocking>: Булево значение, содержащее true, если сервер вызывает
приложение в неблокирующем событийном цикле.

=item *

C<psgi.streaming>: Булево значение, равное true, если сервер ожидает
отложенного ответа в стиле callback и потокового пишущего объекта.

=back

Сервер или приложение может также сохранять свои данные в переменных
окружения. Эти переменные B<ДОЛЖНЫ> содержать по меньшей мере одну точку, и их
B<СЛЕДУЕТ> называть, начиная с уникальной приставки.

Приставка C<psgi.> зарезервирована для использования с основной спецификацией
PSGI, а приставка C<psgix.> зарезервирована для официально одобренных

lib/POD2/RU/PSGI.pod  view on Meta::CPAN

объект L<IO::Handle>, они обратят внимание на значение. Похожим образом
объект, предоставляющий аналогичный API, B<МОЖЕТ> также обратить внимание на
эту специальную переменную, но от него не требуется делать это.

=back

=head2 Отложенный Ответ и Потоковое Тело ответа

The PSGI interface allows applications and servers to provide a
callback-style response instead of the three-element array
reference. This allows for a delayed response and a streaming body
(server push).

Интерфейс PSGI позволяет приложениям и серверам предоставлять ответ в виде
вызываемой функции вместо ссылки на трёхэлементный массив. Это позволяет
возвращать отложенные ответы и потоковое тело ответа (server push).

PSGI серверам B<СЛЕДУЕТ> реализовывать этот интерфейс, и переменная
C<psgi.streaming> должна быть равна true в таких серверах.

Чтобы разрешить отложенный ответ, приложению B<СЛЕДУЕТ> возвращать вызываемую
функцию в качестве ответа. Приложение B<МОЖЕТ> проверять, что переменная
C<psgi.streaming> равна true, и возвращаться к непосредственному ответу, если
это не так.

This callback will be called with I<another> subroutine reference (referred to
as the I<responder> from now on) as its only argument. The I<responder>
should in turn be called with the standard three element array reference
response. This is best illustrated with an example:

Эта вызываемая функция будет вызвана со ссылкой наI<другую> функцию (далее
называемую I<ответчик>) в качестве единственного аргумента. I<Ответчик> должен
в свою очередь быть вызван со стандартным ответом в виде ссылки на

lib/POD2/RU/PSGI.pod  view on Meta::CPAN

1.1: 2010.02.xx

=over 4

=item *

Added optional PSGI keys as extensions: C<psgix.logger> and C<psgix.session>.

=item *

C<psgi.streaming> B<SHOULD> be implemented by PSGI servers, rather than B<MAY>.

=item *

PSGI keys C<psgi.run_once>, C<psgi.nonblocking> and C<psgi.streaming>
B<MUST> be set by PSGI servers.

=item *

Removed C<poll_cb> from writer methods.

=back

=head1 ACKNOWLEDGEMENTS

lib/POD2/RU/PSGI/FAQ.pod  view on Meta::CPAN

работает, но это больше pull, чем push, и сложно делать неблокируемый
ввод/выдать, если только не используется Coro.

Если вы хотите делать push со стороны сервера, где приложение работает в цикле
обработки событий (event loop) и при готовности выдает данные клиенту, следует
вернуть callback для отложенного ответа.

  # long-poll comet подобное чат-приложение
  my $app = sub {
      my $env = shift;
      unless ($env->{'psgi.streaming'}) {
          die "Это приложение требует поддержки psgi.streaming";
      }
      return sub {
          my $respond = shift;
          wait_for_new_message(sub {
              my $message = shift;
              my $body = [ $message->to_json ];
              $respond->([200, ['Content-Type', 'application/json'], $body]);
          });
      };
  };

lib/POD2/RU/PSGI/FAQ.pod  view on Meta::CPAN

разработчиком. В большинстве случаев требуется неблокирующий режим, тогда
следует использовать цикл обработки событий (event loop), как L<AnyEvent>. Также
можно проверить значение C<psgi.nonblocking>, и, если это не поддерживается,
использовать блокирующий вызов.

Для того, чтобы стримить контент (для стриминга сообщений через Flash сокет или
multipart XMLHTTPRequest):

  my $app = sub {
      my $env = shift;
      unless ($env->{'psgi.streaming'}) {
          die "Это приложение требует поддержки psgi.streaming";
      }
      return sub {
          my $respond = shift;
          my $writer = $respond->([200, ['Content-Type', 'text/plain']]);
          wait_for_new_message(sub {
              my $message = shift;
              if ($message) {
                  $writer->write($message->to_json);
              } else {
                  $writer->close;

lib/POD2/RU/PSGI/FAQ.pod  view on Meta::CPAN


Есть серверы, который поддерживают неблокирующий режим (где C<psgi.nonblocking>
имеет true значение), но проблема в том, что серверный фреймворк совсем не
обязательно поддерживает асинхронный цикл обработки событий. Например, в
Catalyst есть метод C<write> у объекта ответа:

  while ($cond) {
      $c->res->write($some_stuff);
  }

Это должно сработать с серверами поддерживающими C<psgi.streaming> даже если они
блокирующие, и если они работают в режиме нескольких процессов
(C<psgi.multiprocess> в значении true).

L<Catalyst::Engine::PSGI> также поддерживает установку IO::Handle-подобного
объекта, который имеет C<getline> метод, пример с L<IO::Handle::Util>

  my $io = io_from_getline sub {
       return $data; # or undef when done()
  };
  $c->res->body($io);

И это работает вполне нормально для стриминга, но это скорее блокирущая операция
(I<pull>), а не асинхронный push со стороны серверы, поэтому, опять же, стоит
быть осторожным при запуске приложения в неблокирующем (и не многопроцессорном)
серверном окружении.

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

=head3 Является ли интерфейс psgi.streaming необходимым для серверов?

Он указан в спецификации как B<SHOULD>, поэтому, если нет серьёзной причины
отказаться от реализации интерфейса, всем серверам рекомендуется реализовывать
этот интерфейс.

Тем не менее, если вы реализовываете PSGI сервер, используя Perl XS интерфейс
для достижения максимальной производительности или интеграции с веб-серверами
вроде Apache или nginx, или создаёте окружение типа "песочницы" (наподобие
Google AppEngine или Heroku), или распределённую платформу, используя утилиты
вроде Gearman, вы можете не захотеть реализовывать этот интерфейс.



( run in 0.543 second using v1.01-cache-2.11-cpan-4d50c553e7e )