Рабочий работник не может найти новую добавленную запись

Я использую 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

Код, который вызывает worker:

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

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

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

Благодарим вас за все комментарии.


person mjaz    schedule 10.02.2010    source источник


Ответы (1)


Вы должны получить минус за создание аукциона в стиле «свупо», и я чувствую себя грязным из-за того, что помогаю вам.

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

так что after_create немного неправильное название - запись еще не создана.

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

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

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

Вот один:

http://github.com/delynn/after_commit

person klochner    schedule 10.02.2010
comment
Я не вижу проблемы в таких аукционах, если вы не вводите людей в заблуждение, когда они регистрируются. Однако ошибка по-прежнему возникает, и любые другие решения были бы очень связаны, если бы я не обидел вас своим выбором приложения. - person mjaz; 10.02.2010
comment
Я читал этот пост раньше. Я не согласен с Этвудом в том, что эти сайты незаконны и являются программным эквивалентом самого Сатаны. На мой взгляд, они не более злы, чем любая социальная игровая платформа, и именно так я собираюсь ее продвигать. Я должен был подумать больше, прежде чем публиковать здесь вопрос об этом конкретном проекте. - person mjaz; 10.02.2010
comment
Аукционы должны способствовать эффективности, а не swoopo. Плохо, если вы рекламируете это как способ покупать вещи по низким ценам. Все устроено так, чтобы выкачивать деньги из людей, которые не понимают, что переплатят и, скорее всего, ничего не получат. - person klochner; 10.02.2010
comment
Тем не менее, см. выше пару вероятных решений. - person klochner; 10.02.2010
comment
Спасибо за помощь, Клохнер. - person mjaz; 10.02.2010