前田製作所さんの作った「ナゼナゼくん」というサービスがおもしろい。

自分の問題だと思っている事柄を入力すると、「なんで××なのですか?」としつこく質問されつづけているうちに、自分と向き合わざるを得なくなるツールです。

まぁ、どんな不満も結局は自分に問題があるという結果になってしまうというか、そうでない方が問題なのだけど、いくらWebサービスとは言え、質問攻めにされるのはいい気分じゃないです。

結構むかむかして、心がささくれだってくるんですが、訳のわからんキャラのせいでどーでもよくなります。

つーか何、残像してんだよ。

Posted in Webサービス at 2月 3rd, 2010. No Comments.

Railsで非同期処理?

railsで非同期処理をやる場合、最近はdelayed_jobメジャーらしいですね。

以前はbackgrounDRbが定番だったようだけど、EngineYardが「友達にBackgrounDRbを使わせるな」とまで書いているので、そこまで言われると使う気になりませんでした。実際リソース食いだったし。

使い方参考ページ

使い方はそんなに難しくないので、ここで説明することは放棄します。

READMERailscastsのエピソード171でなんとかなると思います。

再試行のロジック

いろいろとすっとばして本題、キューの再試行のロジックが変だなぁと思ったのでメモです。

Delayed::Job::max_attempts

delayed_jobには試行回数上限があって、この上限値を超えるまでリトライしつづけます。 デフォルトは25回で、Delayed::Job::max_attempts という定数に設定されています。

Delayed::Worker::sleep_delay

ワーカーが起動するインターバルです。デフォルトは5秒。

例えば絶対に失敗するキューがあった時、

キュー失敗、5秒待機、キュー失敗、5秒待機、(以下25回失敗するまで繰り返し)


という流れを勝手にイメージしていたのですが、そうではないみたいです。

キューが失敗した時の再スケジューリング

キューが失敗すると、次に実行する予定時刻を決めます。そのロジックが

On failure, the job is scheduled again in 5 seconds + N ** 4, where N is the number of retries.

となっています。

「トライした回数の4乗に5秒足した時間」後にリトライをするよう再スケジューリングするので、失敗すればするほどインターバルが開いていきます。

1回失敗したら次回のリトライは6秒後
2回失敗したら次回のリトライは21秒後
3回失敗したら次回のリトライは86秒後
4回失敗したら次回のリトライは261秒後
5回失敗したら次回のリトライは630秒後
6回失敗したら次回のリトライは1301秒後
7回失敗したら次回のリトライは2406秒後
8回失敗したら次回のリトライは4101秒後
9回失敗したら次回のリトライは6566秒後
10回失敗したら次回のリトライは10005秒後

最初の方は1分以内にリトライさせますが、10回目ともなるとリトライは2時間後。
何度も失敗していると、もうこいつアカンわ・・と見捨てられていく感じを良く表現したロジックですねー。

Posted in ruby on rails, 日記 at 12月 15th, 2009. No Comments.

久しぶりにmixiアプリの事を調査したよ。

多分日頃からOpenSocial開発をしてる人には当たり前のことなんだろうけど
ぐぐってもわからなかったので。。

iframeで外部ページを埋め込めるか?

mixiアプリはそもそもiframe内にgadget.xmlをキャッシュされた状態で起動する。

つまり、mixi.jp内のページにmixi-platform.comにキャッシュされたコンテンツを表示していて
さらにその中で別ドメインなコンテンツを表示できるのか?

結論としてはできる。 ただ外部ページからではOpenSocialAPIに接触しようがないから、不便は不便。

iframeの中にfacebookアプリを埋め込んだりもできたよ。
でもmixiアプリ上で認証させるのは多分規約違反。

iframeで外部コンテンツを表示するっていう作法も、外部サイトへの遷移の規約に従ってない気がするのでアウトかな?

どうでしょう?

Flashから外部コンテンツとの通信

OpenSocialのFlash埋め込みAPIを使って、配置したSWFから
URLLoaderなんかを使って普通にクロスドメインな通信ができるかチェック。

これもできる。相手のサーバから拒否されてなければ。

JavaScriptはXHRを使えないから(ひょっとして使える?)、makeRequestするわけだけど
Flashは普通に通信できるなら、mixiアプリは開発しやすさで言えばFlashで作るに限るってことかなぁ。

makeRequestはoAuthの署名リクエストが使えるので、通信にセキュリティを保証したい場合は有効だと思う。

Posted in actionscript3.0, javascript at 11月 19th, 2009. No Comments.

なんかto_jsonについて調べてたら

activerecord/lib/active_record/serializers/json_serializer.rb

にらきすたのこなたが出てくるんだけど、これって有名なんだろうか・・。

あまりにも意外すぎて、なんの作業してたか忘れたよ。いい迷惑だ!

http://github.com/rails/rails/blob/55501b9f6ab46d45db04a81956579402511ad092/activerecord/lib/active_record/serializers/json_serializer.rb#L18-75

--

追記:

例えばこんな感じ、コメントの中にサンプルコードとして登場します

#   konata = User.find(1)
    #   ActiveRecord::Base.include_root_in_json = true
    #   konata.to_json
    #   # => { "user": {"id": 1, "name": "Konata Izumi", "age": 16,
    #                   "created_at": "2006/08/01", "awesome": true} }


はてブのコメントによると2年前からコードの中に存在していたらしい。
アニメ好きな外人のコミッターが犯人だったんすね。

http://blog.codefront.net/2007/10/15/konata-izumi-in-edge-rails/

Posted in ruby on rails at 11月 2nd, 2009. No Comments.

friendship.rb — bdd_sample

RailsCasts大好きです。

  • Rails好き
  • わかりやすい
  • ネタが早い
  • 声が素敵

などいろいろ良い点がありますね。

さて、最近TextMateを使うようになりまして(メインはNetBeansです) あこがれのRailsCastsみたいな色にしたいと奮闘しましたが 本家からダウンロードできるのでした・・

http://railscasts.com/about

好きな人はぜひ!

Posted in ruby at 10月 30th, 2009. No Comments.

RailsでApplicationHelperのスペックを書くときにハマったのでメモ。

準備

まず普通にスペックを書く場合

spec/helpers/appliction_helper_spec.rbを以下のように準備

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe ApplicationHelper, :type => :helper do

  helper_name :application
  %w{hoge}.each do |method_name|
    it "##{method_name}メソッドが存在すること" do
      helper.should be_respond_to(method_name)
    end
  end

end


helper_nameでへルーパー名を定義しておくのがポイント。
そしてExampleの中から「helper」を通じて、エクスペクテーションを書いていきます。(言葉の使い方あってる?)

リクエストを使うスペックを書きたい場合

ヘルパーメソッドの中でリクエストを参照する場合(そもそもヘルパーがリクエストを参照するのが美しいことなのか疑問を抱きましたが、とりあえず無視)

ApplicationControllerにスタブアクションを作ってあげる、というやり方でなんとかしました。

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')

describe ApplicationHelper, :type => :helper do

  class ApplicationController
    def stub_action
      render :text => self
    end
  end

  helper_name :application

  it "ヘルパーの中からリクエストを参照できること" do
    get :stub_action
    helper.mobile_tracking_code.should be_xxxx
  end

end


こんな感じで、普通にコントローラースペックを書くときのようにgetとかpostとかヘルパースペックの中からリクエストを使ったテストを一応かけます。

もっと良い方法がある気がする。

Posted in ruby, ruby on rails at 10月 19th, 2009. No Comments.

個人的メモ

結構リソース食うので次はdelayed_jobにしたい・・

実行してことはあるけど、正常に終了してないキューを取得する

BdrbJobQueue.find(:all, :conditions => ['finished = ? AND taken = ?',0,1])


キューをもう一回実行させる

BdrbJobQueue#release_job


上の合わせ技

BdrbJobQueue.find(:all, :conditions => ['finished = ? AND taken = ?',0,1]).each do |job|
  job.release_job
end


Posted in ruby, ruby on rails at 9月 30th, 2009. No Comments.

Amazon CloudFrontはAmazon S3上のファイルをキャッシュするソリューションです。

前回paperclipからS3を使う設定はわかったので、今回はさらにCloudFrontを利用するための設定です

前回のおさらい

has_attached_file :avatar,
  :storage => :s3,
  :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
  :path => ":attachment/:id/:style.:extension",
  :bucket => 'mybucket'


前回こんな感じでS3の設定をしました。

コンソールから利用してみると

user = User.new
user.avatar = File.open('/tmp/myface.jpg')
user.save

puts user.avatar.url #=> http://mybucket.s3.amazonaws.com/avatar/1/original.jpg


こんな感じでS3のURLがとれるようになっているはず。

s3_host_aliasを効かす

キャッシュサービスであるCloudFrontを利用する場合は、ホスト名を適宜変えるだけなので paperclipが勝手にやってくれるといいなぁ〜なんて思いました。

has_attached_file :avatar,
  :storage => :s3,
  :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
  :path => ":attachment/:id/:style.:extension",
  :bucket => 'mybucket',
  :s3_host_alias => "xxxxxxxxxxxx.cloudfront.net",
  :url => ":s3_alias_url"


オプションが2つ増えてます

  • :s3_host_alias は、エイリアスのFQDNを記述しておきます。
  • :url には「":s3_alias_url"」を記述します。注意なのは、rubyのシンボルじゃなくて、文字列だってところです。ハマりました。
user = User.new
user.avatar = File.open('/tmp/myface.jpg')
user.save

puts user.avatar.url #=> http://xxxxxxxxxxxx.cloudfront.net/avatar/1/original.jpg


わーーこりゃ幸せだ。

余談

さらにサイト全体でアセット関係(public以下)もCloudFrontにしたければ

config/environments/#{RAILS_ENV}.rb 内で

config.action_controller.asset_host = "http://xxxxxxxxxxxx.cloudfront.net"


こうしとけば、image_path()やらimage_tag()やらjavascript_include_tag()やらを使ったときに、リクエスト先を書き換えてくれてさらに幸せ度アップ

Posted in ruby, ruby on rails at 9月 10th, 2009. No Comments.

PaperClipはとってもシンプルなActiveRecordで添付ファイルを管理するプラグインです。

http://github.com/thoughtbot/paperclip/tree/master

便利すぎて鼻血がでそうなプラグインです

使い方のおさらい

カラムを追加して

class AddAvatarColumnsToUser <ActiveRecord::Migration
    def self.up
      add_column :users, :avatar_file_name,    :string
      add_column :users, :avatar_content_type, :string
      add_column :users, :avatar_file_size,    :integer
      add_column :users, :avatar_updated_at,   :datetime
    end

    def self.down
      remove_column :users, :avatar_file_name
      remove_column :users, :avatar_content_type
      remove_column :users, :avatar_file_size
      remove_column :users, :avatar_updated_at
    end
  end


モデルクラスで定義

class User <ActiveRecord::Base
    has_attached_file :avatar
end


とするだけですね。 詳細はRDocをみてください

Amazon S3を使う

PaperClipはストレージにS3を使うためのオプションがあります

has_attached_file :avatar,
    :storage => :s3,
    :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
    :path => ":attachment/:id/:style.:extension",
    :bucket => 'mybucket'


config/s3.ymlには

access_key_id: 456...
secret_access_key: 456...


こんな感じのアクセスキーとシークレットキーを置いておきます

productionでだけS3を使いたい

開発中はローカルで完結したい場合は

has_attached_file :avatar, Proc.new {
    if RAILS_ENV == 'production'
      {
        :storage => :s3,
        :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
        :path => ":attachment/:id/:style.:extension",
        :bucket => 'mybucket'
      }
    else
      {}
    end
  }.call


こんな感じでいいかな

Posted in ruby, ruby on rails at 9月 9th, 2009. No Comments.

こんにちは、久々ですね

Railsでroutes.rbは本当に便利ですよね。

map.resources :users


なんて書くだけで、RESTFulなAPIが用意されます。

  • index
  • new
  • create
  • show
  • edit
  • update
  • destroy

に対応したURLをRailsがよしなにやってくれますよね。

しかし、こんなにたくさんのアクションはいらないー。わしゃcreateとshowだけでいいんじゃーなんて時もあったりします。そんなときは

map.resources :users, :o nly => ['create','show']


として、必要なアクションだけ列挙しましょう。

また、:exceptなんてオプションもあって、必要ないオプションを列挙します。

このへんにかいてありました

Posted in ruby, ruby on rails at 9月 4th, 2009. No Comments.