Кэшировать потоковый ответ? - PullRequest
0 голосов
/ 27 июня 2018

Моя конечная цель - кэшировать дорогостоящую операцию и большие выходные данные, которые я в настоящее время обслуживаю через StreamingResponse. Как? Пожалуйста, помните, что я относительно новичок в Drupal.

Я создал конечную точку API, которая генерирует выходные данные по требованию. Размер вывода может варьироваться - достаточно для того, чтобы я хотел передать ответ - и может меняться полурегулярно (скажем, один или два раза в день).

Потоковая передача - это в основном халява (спасибо Drupal / Symfony!), И у меня это работает:

use Symfony\Component\HttpFoundation\StreamedResponse;

...

public function GETLargishOutputEndpoint ( ) {
  $response = new StreamedResponse(function() {
    # Generate output in streaming fashion, say a large Lorem Ipsum
    while ( $someCriterion ) {
      echo "Lorem ipsum dolor sit amet, consectetur ...";
      $someCriterion = ... # assign true or false
    }
  });

  $response->headers->set('Content-Type', 'x-application/lorem+ipsum');

  return $response;
}

Вывод достаточно дорогой, чтобы создать его, и я хотел бы понести стоимость только один раз за изменение (если только по какой-либо другой причине, кроме опыта пользователя и времени отложенной загрузки). Но как с StreamedResponse? До сих пор Google не был моим другом.

Я согласен с тем, что мне нужно реализовать это вручную и что я не могу использовать CacheableResponseInterface , но надеюсь, что мне не хватает чего-то (не) очевидного.

(это на Drupal 8.5)

1 Ответ

0 голосов
/ 28 июня 2018

Я не разобрался, как работать как с StreamedResponse, так и с извлечением из кеша. Для нашего текущего сценария это выигрыш из кеша; это не будет возможно, если сгенерированный вывод станет слишком большим.

Тем временем рабочий код сводится к базовой парадигме «извлечения из кэша»:

use Symfony\Component\HttpFoundation\StreamedResponse;

...

public function GETLargishOutputEndpoint ( int $nid ) {
  $cid = "some_unique:$nid";

  if ( ! ($cache = \Drupal::cache()->get( $cid ) ) {
    $response = new Response( $cache->data );
  }
  else {
    $node = \Drupal\node\Entity\Node::load( $nid );
    $cache_tags = $node->getCacheTags();

    $data = SomeExpensiveOperation( $nid );

    \Drupal::cache()->set($cid, $data, \Drupal\Core\Cache\CacheBackendInterface::CACHE_PERMANENT, $cache_tags);

    $response = new Response( $data );
  }

  return $response;
}
...