Рабочий не может найти новую запись - PullRequest
0 голосов
/ 10 февраля 2010

Я использую Starling и Workling для обработки фоновых задач в своем приложении, аукционном сайте в стиле Swoopo. В этом случае фоновая задача - это система уведомлений, которая отслеживает аукционы и уведомляет победителя. Монитор вызывается при создании объекта аукциона. Моя проблема в том, что мой контрольный код не может найти аукцион, за которым он должен следить. Вот код:

Проведенный модульный тест:

class AuctionTest < ActiveSupport::TestCase
  test "are monitored when created" do
    auction = Auction.new(
      :name => "A TV",
      :markdown => "A large TV",
      :starting_bid => 0.01,
      :bid_increment => 0.01,
      :starts_at => Time.now(),
      :ends_at => Time.now() + 5.seconds,
      :active => true
    )
    auction.save
    Bid.place(@current_user, auction)

    sleep(10) #when bids are placed, time is added to the end of the auction so wait

    assert auction.won?
    assert_equal @current_user.id, auction.winner_id
  end
end

Рабочий код:

class AuctionsWorker < Workling::Base
  def monitor(options)
    active = true
    ends_at = options[:original_ends_at]
    while active
      auction = Auction.find(options[:auction_id]) #this is the record that cannot be found
      if auction.won?
        active = false
        winner = User.find(auction.high_bidder).id
        auction.update_attribute(:winner_id, winner)
      else
        until Time.now() >= ends_at
          sleep(1)
        end
      end
    end
  end
end

Код, который вызывает работника:

class Auction < ActiveRecord::Base
  def after_create
    AuctionsWorker.asynch_monitor(:auction_id => self.id, :original_ends_at => self.ends_at) if self.active?
  end
end

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

У кого-нибудь есть идеи? Я использую рельсы 2.3.5, sqlite3 и последние версии Starling, Workling и все другие связанные драгоценные камни на Mac OSX 10.6.2 Macbook Pro, если это поможет.

Спасибо за все комментарии.

1 Ответ

0 голосов
/ 10 февраля 2010

Вам следует понизить голосование за создание аукциона в стиле "swoopo-style", а я чувствую себя грязно, что помогаю вам.

after_create () вызывается после Base.save на новые объекты, которые не имеют был сохранен (запись не существует)

поэтому after_create немного ошибочно - запись еще не была создана.

http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M002142

Вы можете добавить свое собственное поле идентификатора и заставить рабочий процесс искать в БД этот идентификатор, спя несколько секунд каждый раз, когда он не находит его (до некоторого заданного предела сбоя).

В качестве альтернативы - вы можете попробовать один из нескольких плагинов after_commit, которые есть на github и которые вызываются после обновления базы данных.

Вот один из них:

http://github.com/delynn/after_commit

...