Ruby on Rails on Windows Azure(4)

一応、このシリーズは今回で終了する予定です(本当?)。これまでのシリーズを振り返ると以下のように記述してきました。

  1. 能楽堂がactiverecord-sqlserver-adapterを含めた理由とAzure対応の目標
  2. Azure対応の目標を立てた理由とホワイトペーパー公開直前のバグ騒ぎ
  3. 能楽堂コンパニオンの解説

何とか、能楽堂 1.1.9の動作確認ができたのが先週末でした。能楽堂 1.1.9の動作確認では、私のrails 3.1.1に対する知識が無かったこともあり、artonさんにはとてもお世話になりました。能楽堂 1.1.9では、能楽堂 1.1.7に比べて新しいパッケージが含まれています。具体的には、以下の通りです。

  • Ruby 1.9.3-p0(1.9.3の正式版です)
  • Rails 3.1.1(能楽堂 1.1.7は、Rails 3.1.0)
  • activerecord-sqlserver-adapter-3.1.3 (SQL AzureでのDBCCバグは修正されています)
  • waz-storage-1.1.1(Azureのストレージサービス用のパッケージです)
    これに伴って、rest-client-1.6.7とruby-hmac-0.4.0も追加されています。

私の無知が何かということを説明すると、Assetsに対する動作が Rails 3.1.0 と Rails 3.1.1で変更されていたことに気が付かなったことです。正確かどうかは不明ですが、私が遭遇した現象は以下のようなものです。

  • Rails 3.1.0:Assetsのリクエストを処理していたのがRailsらしい(production.logに記録される)。
  • Rails 3.1.1:Assetsのリクエストを処理するのはRailsからWebサーバーになった(production.logにルーティングエラーが記録される)。

この理由から、Rails 3.1.1 ではAssetsをEnnouに処理させなければなりません。この設定は、config/environments/production.rbで config.serve_static_assetstrue にします。この設定に辿り着くまでに、時間がかかってしまいました。

この設定が理解できたので、NougakuDoCompanionでは以下のような設定方法を追加しています。

  • config/environments/production.rb は、config.server_static_assets を必ず true に設定。
  • config/environment.rb は、Rails 3.1.xの場合に ENV['RAILS_RELATIVE_URL_ROOT'] を設定。
  • config/application.rb は、Rails 3.0.xの場合に config.action_controller.asset_path を設定。

この変更が完了してから、能楽堂 1.0.5、1.1.7、1.1.9で作成した Rails アプリケーションの動作確認ができてから NougakuDoCompanion v1.0 として公開しました。公開したcspkgには、Small、Medium、Large、Extra Largeを入れていますので、xsで使用しない限りはソースコードからビルドする必要がなくなっています。もちろん、ソースコードも公開しています。

ホワイトペーパーの環境は、能楽堂 1.1.7なのでRailsは3.1.0になります。Rails が 3.1.1になったことで、Assetsのプリコンパイルに関する手順で変更があり、具体的な内容を以下に示します。

 # NougakuDo - prompt で作業を行います
use_closure アプリケーションのディレクトリー名

# use_closureを使用しない場合は、config/environemnts/production.rb を以下のように編集します
config.assets.compress = false

この理由は、uglifier-1.0.4 の JScript対応に問題があるためです。この理由から、能楽堂 1.1.9では、use_closureコマンドを用意して JavaScript の圧縮をclosure-compiler で行うように変更することができます。closure-compiler を使用するためには、JRE 6 が必要になりますので、「rake assets:precompile」 コマンドを実行する前に java.exeに対するパスを追加しておく必要があります。
closure-compilerは、JavaScriptの圧縮に必要になるだけで、Railsの実行時に JRE 6 を必要としません。つまり、Azureのコンピュート サービスにJREは必要がないということです。 

それから能楽堂 1.1.9で追加されたwaz-storageですが、私からartonさんにお願いして追加していただきました。このパッケージは、waz-cmdなどで使用されているもので、せっかくRubyを使用するのですから、Azure Storage Explporerなど使用しないでAzureのストレージサービスにNougakuDoCompanionで必要とする設定情報をアップロードするのとRailsアプリケーションからも使用できるようにしたいと考えたからです。 waz-storageを簡単に使用するためのサンプルを以下に示します。

 class Uploader
  require 'waz-blobs'
  def initialize(options = {})
    my_options = {}
    if (options[':use_devenv'])
      my_options[:account_name] = 'devstoreaccount1'
      my_options[:access_key] = 'Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=='
      my_options[:use_devenv] = true
      my_options[:base_url] = '127.0.0.1:10000'
      my_options[:use_ssl] = true if options[:use_ssl]
    else
      my_options = options.dup
    end
    WAZ::Storage::Base.establish_connection!(my_options)
  end

  def connect?
    WAZ::Storage::Base.connected?
  end

  def upload(name, filename)
    fname = File::basename(filename)
    container = get_container(name)
    File.open(filename, 'rb') do |fp|
      container.upload(fname, fp, 'application/octet-stream')
    end
  end

  def get_container(name)
    container = WAZ::Blobs::Container.find(name)
    container = WAZ::Blobs::Container.create(name) if container.nil?
    container
  end
end

#使い方
uploader = Uploader.new(:use_devenv => true)
uploader.upload('nougakudo', 'C:\data\NougakuDo.zip')

こんな感じで使用します。waz-storageでは、establish_connection!メソッドによって指定したオプション毎に接続がキャッシュされていき、最後の接続がdefault_connectionになります。establish_connectionメソッドを使えば、キャッシュした接続を切り替えたり、新しい接続を作成したりすることができます。使ってみた感じでは、バグが無いとは云いませんが、アップロードやダウンロード用途にはそれなりに使用することができます。SDKのStorage エミュレーターを使う時は、指定するオプションが多いのでサンプルではクラスにしています。Azure上のストレージサービスを使用する場合であれば、:accout_name、:access_keyと:use_sslを指定するだけになります。 NougakuDoComapnionを使用する場合に、是非ともwaz-storageを使用してみてください。

追記:uglifier の最新版である 1.1.0 をインストールして確認したところ、rake assets:procompile コマンドのエラーは無くなっていました。このことから、uglifier-1.0.4 が持っていた JScript対応のバグは解消したと考えられます。uglifier-1.1.0をインストールした場合は、use_closure コマンドの実行は不要になります。