Рельсы асинхронной обработки в модели - PullRequest
0 голосов
/ 07 мая 2011

В моем приложении rails есть простая модель Links, которая отслеживает все URL-адреса, связанные с обновлением.

class Link
include Mongoid::Document
include Mongoid::Timestamps

field :url, type: String
field :domain, type: String
attr_accessible :url, :domain

validates_uniqueness_of :url

has_and_belongs_to_many :updates

before_create :longenate

Но прежде чем создавать объект, я бы хотел избавиться от любого сокращения URL-адреса для различныхПричины, такие как долговечность ссылки и в целом просто не нравятся сокращения.

В настоящее время моя функция longenate очень наивна (все еще в разработке, поэтому она должна быть :)), и создает довольно узкое место, поскольку она блокируется во время запросаЭто может занять довольно много времени, если за один раз создается довольно много обновлений, и обычно создается несколько десятков.Поскольку обновления / ссылки и т. Д. Необходимо быстро отобразить обратно пользователю, это проблема.

    http_client = HTTPClient.new(:agent_name => "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)")
begin
    head_res = http_client.head(url)
    unless head_res.header['Location'].empty?
        short_url = url
        self.url = head_res.header['Location'][0]    
    end
rescue Exception => e
    self.domain = "ERROR ACCESSING URI"
    self.url = "Error Accessing URI, site down/non existant?"
end

Я хотел бы поменять это на что-то неблокирующее.Я знаком с eventmachine и использовал его для создания простых сервисов и потребителей, но все еще относительно новичок в рельсах.Каков будет лучший подход к рельсам для чего-то подобного?Функция «финализации», включающая в себя машинный цикл событий, позволяющий удлинить / создать все Связи за один раз или, возможно, выполнить (как-то) внутри модели, чтобы она запускала асинхронную задачу при ее создании?

Спасибо за любые советы / ресурсы

1 Ответ

1 голос
/ 07 мая 2011

Существует несколько структур фоновой обработки (delayedjob, stalker, resque и т. Д.) .... Возможно, проще всего начать работу с Delayed Job.

Как только вы установили delayedjob (установка gem плюс миграция), вы можете сделать что-то вроде:

class Link
  ..
  before_create :longenate
  def longenate
    # do your stuff
    self.save
  end
  handle_asychronously :longenate
end

Затем работники будут выполнять свою работу, используя rake jobs:work.Это будет происходить в фоновом режиме;с этой реализацией вы будете сохранять записи, которые не были longenate'd, так что вы можете захотеть поле 'status', которое указывает, было ли оно longenate или нет.

Дополнительная информация: http://www.therailsway.com/2009/7/22/do-it-later-with-delayed-job

...