2009-05-22 8 views
0

Railsには、オブザーバのサポートだけでなく、before_validation、before_create、after_saveなどのフィルタセットが用意されていますが、フィルタまたはオブザーバは計算コストが非常に高い。私は代わりが必要です。Ruby on Railsプロジェクトのフィルタ/オブザーバの代替手段が必要

問題:Webサーバーのヒット数を多数のページに記録しています。私が必要とするのは、特定のページがX回以上閲覧されたときにアクションを実行する(たとえば、電子メールを送信する)トリガーです。膨大な数のページとヒットがあるため、フィルタやオブザーバを使用すると、時間の99%がテストされる条件がfalseになるため、無駄な時間が掛かります。メールはでなくですぐに送信する必要があります(つまり、5〜10分の遅延が許容されます)。

私が代わりに考えているのは、5分ごとにデータベースを掃引し、どのページがX回以上ヒットしたかを確認し、その状態を新しいDBテーブルに記録してから送信することです対応する電子メール。正確にエレガントではありませんが、うまくいくでしょう。

もっと良いアイデアはありますか?

+0

私は徹底的に調査していないので、これを投稿したくありませんが、問題のドメイン内に 'rails cron'のgoogle検索がありますか?もしそうなら、私はあなたの質問がより具体的であるかもしれないと確信しています。 –

+0

私は知っている!あなたが処理時間の99%を節約する、それが真実であるときだけ条件をテストしてください。 :D –

答えて

0

ヒットモデルを保存するときに、ヒット数が多いページモデルの冗長な列を更新すると、2回の追加クエリが発生するため、処理に2回かかることがありますが、単純な場合は、電子メールを送信する必要があります。

あなたの元の解決策も悪くありません。

0

ここでは、stackoverflowが最初の行をコードハイライトするように記述する必要があります。

class ApplicationController < ActionController::Base 
    before_filter :increment_fancy_counter 

    private 

    def increment_fancy_counter 
    # somehow increment the counter here 
    end 
end 

# lib/tasks/fancy_counter.rake 
namespace :fancy_counter do 
    task :process do 
    # somehow process the counter here 
    end 
end 

は、しかし、多くの場合、あなたはそれを実行したいcronジョブの実行rake fancy_counter:processを持っています。

+0

私はそれをレーキ:仕事にすることは考えていませんでした。ありがとう! –

1

レーキタスクは素晴らしいです!しかし、追加するバックグラウンドジョブごとにカスタムコードを書くことになります。遅延ジョブプラグインをチェックしてくださいhttp://blog.leetsoft.com/2008/2/17/delayed-job-dj

DJは1つの単純なデータベーステーブルに依存する非同期優先キューです。 DJウェブサイトによれば、Dayayed :: Job.enqueue()メソッドを使用してジョブを作成することができます。ドキュメントあたりのヒット数を監視し、それらが一定のしきい値に達すると、何かの操作を行います。

class NewsletterJob < Struct.new(:text, :emails) 
    def perform 
    emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) } 
    end  
end 

Delayed::Job.enqueue(NewsletterJob.new("blah blah", Customers.find(:all).collect(&:email))) 
+0

+1、既に数十億ものものが実装されている場合、バックグラウンドジョブデーモンを書く必要はありません。バックグラウンドジョブ、Beanstalkd、遅れた仕事.... –

1

は、私はかつて同じ要件を持つカスタム広告サーバーを、書いたチームの一員でした。このサーバーは、トラフィックが多い既存の非常に大きなサイトに動力を与えようとしており、スケーラビリティは本当の懸念事項でした。私の会社は、脳を選ぶために2人のDoubleclickコンサルタントを雇いました。

彼らの意見は:どの情報も永続化させる最速の方法は、それをカスタムApacheログ指示文に書き込むことです。そこで、誰かがドキュメント(広告、ページ、すべて同じ)を押すたびに、リクエストを処理したサーバーがSQLステートメントをログに書き込むサイトを構築しました。 "INSERT INTOインプレッション(タイムスタンプ、ページ、IPなど) )VALUES(x、 'path/to/doc'、yなど); " - ウェブサーバーからのデータをすべて動的に出力します。 5分ごとに、これらのファイルをWebサーバーから収集し、それらをすべてマスターデータベースに一度に1つずつダンプします。それから、私たちの余暇では、私たちはそのデータを解析して、私たちがそれに満足する何かをすることができました。

正確な要件と展開の設定に応じて、同様のことを行うことができます。特定のしきい値を超えているかどうかを確認するための計算上の必要条件は、SQLを実行して値を増やしたり、行を挿入したりするよりも、おそらくさらに小さくなります(ここで推測します)。ヒット(特別なフォーマットかどうか)を記録することによってオーバーヘッドの両方のビットを取り除き、定期的にそれらを収集し、解析し、それらをデータベースに入力し、必要なものを実行することができます。