Синатра: распространение событий

Я работаю над небольшим приложением. Отправив задачу, пользователь может получать серию сообщений о состоянии - таким образом, можно понять, была ли производительность успешной или нет. Это может быть реализовано с подпиской на события SSE и JS. Проблема в распределении событий и изоляции переменных - я никогда не работал с несколькими арендаторами.

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

Я знаю, как реализовать механизм аутентификации и как предоставить каждой задаче уникальный идентификатор, но как мне реализовать мультитенантность в приложении Sinatra? Есть много драгоценных камней и рецептов, но все они написаны для RoR.

Мое приложение обеспечивает обработку факсов Asterisk. Он состоит из двух частей: первая - обработчики маршрутов Синатры, вторая - бэкэнд-процесс - он прослушивает события Asterisk (AMI), а также обеспечивает отправку новой задачи.

Как говорят люди, все еще трудно понять, что должно делать мое приложение, я опишу это шаг за шагом.

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

Но этого не происходит: пользователи видят беспорядок двух потоков событий. Это моя проблема.

На самом деле моя задача аналогична реализации чата с той разницей, что люди не должны разговаривать друг с другом. Предполагается, что они "общаются" с фоновым процессом через сервер. Каждый может сказать "Hello", сервер перенаправляет "Hello" в фоновый процесс, а затем возвращает из фонового процесса частный поток ответов владельцу, это происходит асинхронно. В чате вы можете сказать "Привет" другому приятелю, вы никогда не знаете, когда получите ответ, но сервер знает, что этот ответ ваш, и вы получите свой личный ответ.

Вот фрагменты:

class FaxServer < Sinatra::Base
 ...
 post '/run' do
  settings.backend_process.async.run(param1, param2)
 end
 ...
end

class MyBackendProcess
 def run(number, file)
  if File.exist?(file) then
   change_status("Calling attempt, please wait...")
   $stream.async.send_action ...
 end
 ...
 def handle_event(event)
  case
  when event.name === "Newchannel"
  change_status("New channel is created")
  ...
 end
end

class StatusSender
 include Celluloid
 include Celluloid::Notifications

 def send_status(message)
  publish("status_event", "#{Time.now.strftime('%R:%S')} : #{message}")
 end
end

class StatusObserver
  include Celluloid
  include Celluloid::Notifications

  def initialize(server)
    @server = server
    subscribe "status_event", :status_event 
  end

  def status_event(*args)
    @server.settings.connections.each { |out| out << "event: #{args[0].to_s}\ndata: #{args[1]}\n\n" }
  end
end

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

0 ответов

Другие вопросы по тегам