Сообщение Action Cable Broadcast fron sidekiq отображается только после обновления, мгновенно работает с консоли - PullRequest
4 голосов
/ 05 июня 2019

Я следовал этому руководству , чтобы создать кабельное вещание, но оно не совсем работает, как ожидалось.Каналы и веб-приложение успешно подписываются, но сообщения , транслируемые из фонового задания sidekiq, отображаются только после обновления страницы . Использование этой же команды на консоли приводит к немедленному обновлению страницы .

При просмотре кадров в режиме разработчика Chrome я не вижу сообщения, передаваемые из фонового задания, номожно сразу увидеть те, что отправлены с консоли.Однако я могу подтвердить, что фоновое задание sidekiq где-то передает эти сообщения, так как они появляются при обновлении;однако, я не знаю, где они стоят в очереди.

Существуют ли какие-либо дополнительные изменения конфигурации, необходимые для того, чтобы сообщения из фонового задания не помещались в очередь?Есть ли какие-либо опечатки или ошибки в моем коде, которые могут быть причиной этого?

Action Cable Broadcast:

ActionCable.server.broadcast "worker_channel", {html:
      "<div class='alert alert-success alert-block text-center'>
        Market data retrieval complete.
    </div>"
    }

smart_worker.rb: - ​​Это называется execute_async из действия контроллера

class SmartWorker
  include Sidekiq::Worker
  include ApplicationHelper
  sidekiq_options retry: false

 def perform
   ActionCable.server.broadcast "worker_channel", {html:
      "<div class='alert alert-success alert-block text-center'>
        Market data retrieval complete.
    </div>"
    }
 end

connection.rb:

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = current_user #find_verified_user ignored until method implemented correctly and does not always return unauthorized
    end

    private 

    def find_verified_user
      if current_user = User.find_by(id: cookies.signed[:user_id]) 
        current_user
      else
        reject_unauthorized_connection
      end
    end
  end
end

worker_channel:

class WorkerChannel < ApplicationCable::Channel
  def subscribed
    stream_from "worker_channel"
  end 

  def unsubscribed
  end
end

worker.js:

App.notifications = App.cable.subscriptions.create('WorkerChannel', {
  connected: function() {
    console.log('message connected');
  },
  disconnected: function() {},
  received: function(data) {
    console.log('message recieved');
    $('#notifications').html(data.html);
  }
});

cable.yml

development:
  adapter: redis
  url: redis://localhost:6379/1

test:
  adapter: async

production:
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: smarthost_production

Также добавлено

к представлению, но это не имеет значения.

Ответы [ 2 ]

0 голосов
/ 17 июня 2019

Я не уверен, что это полное объяснение, но это то, что я наблюдал при дальнейшем тестировании:

После перезапуска нескольких серверов широковещательная рассылка начала работать и регистрировалась, как и ожидалось, в регистраторе разработки.Консольные сообщения по-прежнему попадают или пропускают, поэтому я добавил некоторые дополнительные идентификаторы к передаваемым сообщениям и определил, что они транслируются до завершения загрузки следующей страницы.Это вызвало две вещи: 1) быстрое мигание флеш-сообщений, инициированных трансляцией (в том, что воспринималось как старая страница - т.е. работает только после обновления) 2) отсутствие или непоследовательное поведение в консоли браузера:Задание sidekiq выполняется так быстро, что даже до того, как браузер начал рендеринг новой страницы, я считаю, что консольные сообщения сбрасываются при загрузке страницы и поэтому не видны при проверке журналов (или даже если вы смотрите на негокакое-то время).

Кажется, что это работает так, как ожидалось, и просто работает быстро в локальной среде, из-за чего создается впечатление, что оно работает не так, как задумано.

0 голосов
/ 11 июня 2019

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

Я бы проверил:

  1. Запустите всю работу в консоли, а не только уведомления, и посмотрите, работает ли она медленно
  2. Проверка латентности очередей sidekiq
  3. Добавьте ведение журнала до / после уведомления в задании и проверьте журналы, если задание действительно успешно выполнено
...