Infobar C01
ドライバのインストールにちょっと躓いたのでメモ。
http://oyasis.com/articles/518
check_dependencies
古い作り方のまんまになっているgem(rubeus)をbundlerを使う形にしようとして、まずGemfileを作ってrakeしたらこんなエラーが。
$ rake rake aborted! Don't know how to build task 'check_dependencies'
ぐぐってもよく分からないのでjewelerのソースコード読んだらcheck_dependenciesタスクはGemfileがないときだけ定義されるということが分かりました。最初からソース読めば良かったw
https://github.com/technicalpickles/jeweler/blob/master/lib/jeweler/tasks.rb#L187
結局Rakefileからcheck_dependenciesを削除して事なきを得ました
[java][ruby] JRubyからJavaのHttpClientを使う
今日、railsで作ってるサーバへの疎通確認をしてもらってたんですが、サーバとクライアントのどちらに問題があるのかわからなかったので、問題を切り分けるためにクライアント側で使うライブラリでちゃんとアクセスできるかどうか確認することにしました。
クライアントはJavaのhttpclientを使っているので、僕としては当然JRubyで使うわけです。書いたコードはこんな感じです。
localhostに対してGET /foo.json で得られたbarを POST /bazのパラメータとして使って送信してます
# -*- coding: utf-8 -*- require 'java' require 'rubygems' require 'json' # カレントディレクトリのlib以下に使用するjarを置いてください。 # jarは http://hc.apache.org/downloads.cgi のBinary とかからゲット可能です。 Dir['./lib/*.jar'].each{|f| require f} import "java.io.BufferedReader" import "java.io.InputStreamReader" import "java.net.URLEncoder" import "java.util.ArrayList" import "org.apache.http.client.entity.UrlEncodedFormEntity" import "org.apache.http.client.methods.HttpPost" import "org.apache.http.client.methods.HttpGet" import "org.apache.http.entity.StringEntity" import "org.apache.http.impl.client.DefaultHttpClient" import "org.apache.http.message.BasicNameValuePair" import "org.apache.http.protocol.HTTP" client = DefaultHttpClient.new req = HttpGet.new("http://localhost/foo.json") res = client.execute(req) puts "status_code: #{res.getStatusLine.toString}" rd = BufferedReader.new(InputStreamReader.new(res.getEntity.getContent)) lines = [] while line = rd.readLine lines << line end res_obj = JSON.parse(lines.join) # このJSONのparseはRubyのgemである"json"を使って行っています。 bar = res_obj['bar'] # GET /foo.json で得られたbarを POST /bazのパラメータとして使う req = HttpPost.new("http://localhost/baz") values = ArrayList.new(1) values.add(BasicNameValuePair.new("bar", bar)) req.setEntity(UrlEncodedFormEntity.new(values, HTTP::UTF_8)) res = client.execute(req) puts "status_code: #{res.getStatusLine.toString}" rd = BufferedReader.new(InputStreamReader.new(res.getEntity.getContent)) while line = rd.readLine puts line end
難しいRubyの文法を使わなかったのでJavaでクライアント側の実装をやってる人に読んでもらえたのが良かったです。
でも通信自身とは関係ない部分で、さりげなくJSON.parseとかRubyのライブラリを組み合わせて使っています。
rvmさえインストールされていれば、
$ rvm install jruby $ rvm jruby $ gem install json
で上記に必要なインストールは完了するはず。
あとは上のファイルの名前を java_httpclient_example.rb とするなら
$ jruby -S java_httpclient_example.rb
とかで実行できちゃいます。コンパイル不要です。
ちょっとだけJavaのライブラリを触るときにはこんな感じでやれると楽だなーと久しぶりに実感しました。
pushしちゃったコミットのコメントを直す方法
結論。そのリポジトリは捨てて作り直そう。
方法。git filter-branchやgit rebase -i (のreword)などでコメントを変更することはできるけど、そうすると変更されたコメントの新しいコミットが作られるだけで古いコメントのコミットも残る。
この古いコメントのコミットは、新たに作るリポジトリにはコミットしないで、新しいコミットの方のブランチだけをコミットすればOK。
あと、新しいリポジトリに移行したいブランチはちゃんとローカルに作っておかないと、pushできないのでちゃんとbranchをローカルに作るべし。
$ git checkout 移行したいブランチ名
でoriginを削除
$ git remote rm origin
コメントの修正はfilter-branchが楽です。 ( http://www.clear-code.com/blog/2012/1/5.html で紹介されている例 )
$ git filter-branch --msg-filter 'sed -e "s/Merge.*internal.*\$/Merge/"' -f
で、ここで新しく作られたブランチと、古いブランチがちゃんと分かれていることを確認したら、それを新しいリポジトリに移行しよう。
まず新しいリポジトリを作る。
githubならadmin画面からdeleteして、もう一回同じ名前で作るのはアリ。
ただしチームのメンバーに同じ名前だけど別物だから気を付けてね、と話しておく必要がある。
次にoriginを再設定する
$ git remote add origin 新しいリポジトリのURL
移行したいブランチをpushしまくる
$ git push origin 移行したいブランチ名
それからタグ関係も一緒に移行できればいいんだけど、古いブランチの方に付けられているので、無理っぽい。
自分で新旧のコミットのコメントを読んで新しい方に手動でタグを貼るしかなさそう。
これで多分オッケーなはず。
明日は勉強会やります
「イケテルRails3.1勉強会
RailsGuides から Routing 周りをみてみよう」と題してREST周りの話をします。
RailsGuidesを使ったハンズオンとかもやります。
お申し込みはこちら
http://atnd.org/events/24169
developmentを実現したいのでコードを読んでみる#5
昨日ログを出力するように変更したrailsを使って、ほとんど素のrails3のアプリでサーバの起動、GETリクエストx3、サーバの停止までにActionDispatch::Reloaderの各メソッドがどのように呼びだされるのか、developmentとproductionの場合それぞれについて出力してみました。
https://github.com/akm/rails3_reloader_study/blob/master/actiondispatch_reloader_method_invocations_development.log
https://github.com/akm/rails3_reloader_study/blob/master/actiondispatch_reloader_method_invocations_production.log
production
起動時
ActionDispatch::Reloader.to_cleanup(
module Rails class Application module Bootstrap include Initializable # (中略) initializer :set_clear_dependencies_hook, :group => :all do ActionDispatch::Reloader.to_cleanup do ActiveSupport::DescendantsTracker.clear ActiveSupport::Dependencies.clear end end
ActionDispatch::Reloader.to_prepare(
module I18n class Railtie < Rails::Railtie # (中略) initializer "i18n.callbacks" do ActionDispatch::Reloader.to_prepare do I18n::Railtie.reloader.execute_if_updated end end
ActionDispatch::Reloader.prepare!
ActionDispatch::Reloader#initialize(nil)
module Rails class Application module Finisher include Initializable # (中略) initializer :run_prepare_callbacks do ActionDispatch::Reloader.prepare! end
module ActionDispatch class Reloader include ActiveSupport::Callbacks # (中略) # Execute all prepare callbacks. def self.prepare! self.trace_log(:prepare!) new(nil).run_callbacks :prepare end
GET /tests/foo?idx=1
ActionDispatch::Reloader.to_prepare(
module Rails class Application module Finisher include Initializable # (中略) initializer :set_routes_reloader do |app| reloader = lambda { app.routes_reloader.execute_if_updated } reloader.call ActionDispatch::Reloader.to_prepare(&reloader) end
ActionDispatch::Reloader.to_cleanup(
ActionDispatch::Reloader.to_prepare(
module ActiveRecord # = Active Record Railtie class Railtie < Rails::Railtie # (中略) initializer "active_record.set_dispatch_hooks", :before => :set_clear_dependencies_hook do |app| ActiveSupport.on_load(:active_record) do ActionDispatch::Reloader.to_cleanup do ActiveRecord::Base.clear_reloadable_connections! ActiveRecord::Base.clear_cache! end end end config.after_initialize do ActiveSupport.on_load(:active_record) do instantiate_observers ActionDispatch::Reloader.to_prepare do ActiveRecord::Base.instantiate_observers end end end
GET /tests/foo?idx=2
なし
GET /tests/foo?idx=3
なし
サーバを停止
なし
まとめ
development
起動時
ActionDispatch::Reloader.to_cleanup(
ActionDispatch::Reloader.to_prepare(
これらはproductionと同じ。
ActionDispatch::Reloader#initialize(#
/Users/akima/workspace/rails/actionpack/lib/action_dispatch/middleware/stack.rb:112:in `build' /Users/akima/workspace/rails/railties/lib/rails/engine.rb:447:in `app'
module ActionDispatch class MiddlewareStack # (中略) def build(app = nil, &block) app ||= block raise "MiddlewareStack#build requires an app" unless app middlewares.reverse.inject(app) { |a, e| e.build(a) } end
module Rails class Engine < Railtie # (中略) def app @app ||= begin config.middleware = config.middleware.merge_into(default_middleware_stack) config.middleware.build(endpoint) end end
GET /tests/foo?idx=1
ActionDispatch::Reloader.prepare!
ActionDispatch::Reloader#initialize(nil)
これらはproductionの起動時に実行されるものと同じ
ActionDispatch::Reloader.to_prepare(
productionのGET /tests/foo?idx=1で実行されるものと同じ
ActionDispatch::Reloader#call({"GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/tests/foo", "QUERY_STRING"=>"idx=1", ...)
module Rack class Sendfile # (中略) def call(env) status, headers, body = @app.call(env) if body.respond_to?(:to_path) case type = variation(env)
ActionDispatch::Reloader.to_cleanup(
ActionDispatch::Reloader.to_prepare(
productionのGET /tests/foo?idx=1で実行されるものと同じ
ActiveRecord::ConnectionAdapters::ConnectionManagement::Proxy#close
ActionDispatch::Reloader.cleanup!
ActionDispatch::Reloader#initialize(nil)
module Rack module Handler def service(req, res) # (中略) status, headers, body = @app.call(env) begin res.status = status.to_i headers.each { |k, vs| if k.downcase == "set-cookie" res.cookies.concat vs.split("\n") else # Since WEBrick won't accept repeated headers, # merge the values per RFC 1945 section 4.2. res[k] = vs.split("\n").join(", ") end } body.each { |part| res.body << part } ensure body.close if body.respond_to? :close end end
module ActionDispatch class Reloader # (中略) # Execute all cleanup callbacks. def self.cleanup! self.trace_log(:cleanup!) new(nil).run_callbacks :cleanup end # (中略) module CleanupOnClose def close ActionDispatch::Reloader.trace_log_impl("#{self.class.name}#close") super if defined?(super) ensure ActionDispatch::Reloader.cleanup! end end
GET /tests/foo?idx=2
ActionDispatch::Reloader#call({"GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/tests/foo", "QUERY_STRING"=>"idx=2", ...)
GET /tests/foo?idx=3
ActiveRecord::ConnectionAdapters::ConnectionManagement::Proxy#close
ActionDispatch::Reloader.cleanup!
ActionDispatch::Reloader#initialize(nil)
ActionDispatch::Reloader#call({"GATEWAY_INTERFACE"=>"CGI/1.1", "PATH_INFO"=>"/tests/foo", "QUERY_STRING"=>"idx=3", ...)
サーバを停止
ActiveRecord::ConnectionAdapters::ConnectionManagement::Proxy#close
ActionDispatch::Reloader.cleanup!
ActionDispatch::Reloader#initialize(nil)