Проблема с таймером Mojo :: IOLoop перед перенаправлением - PullRequest
1 голос
/ 08 марта 2019

У меня есть подпрограмма в моем контроллере Mojolicious, которая вызывается, когда файл csv загружается через сообщение http.После загрузки файла выдается сообщение, в котором говорится, что «вы будете перенаправлены через x секунд».поэтому я хочу реализовать Mojo :: IOLoop :: Delay и в качестве обратного вызова я использую оператор перенаправления.Но я получаю следующую ошибку от Морбо:

Mojo::Reactor::EV: Timer failed: Transaction already destroyed at /usr/local/share/perl/5.22.1/Mojolicious/Plugin/DefaultHelpers.pm line 168.

код контроллера:

sub upload {
    my $self = shift;
      # Check file size
      return $self->render(text => 'File is too big.', status => 200)
      if $self->req->is_limit_exceeded;

  # Process uploaded file
  return $self->redirect_to('/') unless my $newCsv = $self->param('fileToUpload');
  my $size = $newCsv->size;
  my $name = $newCsv->filename;
  my $delay = 2;
  $self->render(text => "Thanks for uploading $size byte file $name.<br>
    You will be redirected in $delay seconds");
  Mojo::IOLoop->timer($delay => sub {
    $self->redirect_to('/');
    });
}

соответствующие маршруты:

$r->get('/')->to(controller => 'main', action => 'index');
$r->post('/uploadCsv')->to(controller => 'main', action => 'upload')->name('uploadCsv');

Заранее спасибо

Ответы [ 2 ]

2 голосов
/ 08 марта 2019

redirect_to фактически является render, который отображает ответ HTTP 302 для перенаправления. Вы не можете выполнить рендеринг дважды, поэтому, даже если вы удерживаете транзакцию до вызова redirect_to, она уже отобразила бы страницу. Таким образом, есть два фактических варианта того, что вы пытаетесь сделать; визуализировать страницу с использованием JavaScript, который будет выполнять перенаправление после истечения времени ожидания, или визуализировать HTML-страницу с мета-тегом обновления, который приведет к перенаправлению страницы после задержки. На этой странице MDN обсуждаются оба подхода.

1 голос
/ 08 марта 2019

upload возвращается после Mojo::IOLoop->timer и таймер не ждет.Вы можете попробовать использовать Mojo :: IOLoop-> delay и $delay->wait.Но я не уверен, как это работает.Так что это может быть эквивалентно просто sleep.

Вам действительно нужно перенаправить из кода Perl?Вы можете визуализировать некоторые js с setTimeout для того же эффекта.

На самом деле, я бы порекомендовал переместить весь текст и перенаправить на js и рендерить только json с некоторой информацией о состоянии внутри upload.Таким образом, вы можете реализовать лучший интерфейс с обработкой ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...