Сегодня ночью понял, что вслед за книгой the Ruby way дал маху и имел лишний вызов DRb.start_service на клиенте. Если почитать документацию, то в комментариях сэмпл кода выясняется, что это требуется далеко не всегда и уже в доке к классу DRbServer выясняются детали. А ведь пока в сорец не залез - не понял. А это устранило единственный крупный bottleneck в приложении.
Вот и читай после этого полезные книги.
27 августа 2009
Using DRb
на 10:41 0 коммент.
10 августа 2009
Camping 1.9, Passenger & ruby 1.9
Стремление найти себе на разные места приключений никогда не покидает таких как я, вот и захотелось завести текущий проект под ruby 1.9.1 и перевести под passenger.
Пара слов - по общему моему впечатлению, мир руби не готов ещё использовать 1.9.1. То одно, то другое не работает, приходится хачить уже написанное, вставлять проверки версии языка, что-то вообще не лечится (так, у меня не завёлся монгрел, даже после советов с isitruby19.com)
Начнём с самого ruby. Даже на InfoQ засветился скрипт для установки и переключения разных версий Ruby: ruby_swither.
Однако для моей цели пришлось внести в него поравки в секции для 1.9.1 (OMG, опять на одну маленькую строчку я убил полдня):
gem install camping --source http://gems.judofyr.net
Сам camping придётся поправить, вот патчик:
+++ /Users/phoenix/.ruby_versions/ruby-1.9.1-p129/lib/ruby/gems/1.9.1/gems/camping-1.9.316/lib/camping.rb 2009-08-09 18:07:48.000000000 +0600
@@ -3,12 +3,12 @@
S=IO.read(__FILE__)rescue nil;P="<h1>Cam\ping Problem!</h1><h2>%s</h2>"
U=Rack::Utils;Apps=[];class H<Hash
def method_missing m,*a;m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.to_s]:super end
-undef id,type;end;module Helpers;def R c,*g
+undef id,type if respond_to? :id;end;module Helpers;def R c,*g
p,h=/\(.+?\)/,g.grep(Hash);g-=h;raise"bad route"unless u=c.urls.find{|x|
break x if x.scan(p).size==g.size&&/^#{x}\/?$/=~(x=g.inject(x){|x,a|
x.sub p,U.escape((a[a.class.primary_key]rescue a))})}
h.any?? u+"?"+U.build_query(h[0]):u end;def / p
-p[0]==?/?@root+p:p end;def URL c='/',*a;c=R(c, *a) if c.respond_to?:urls
+p[0]==?/?@root+p : p end;def URL c='/',*a;c=R(c, *a) if c.respond_to?:urls
c=self/c;c=@request.url[/.{8,}?(?=\/)/]+c if c[0]==?/;URI c end
end;module Base;attr_accessor:input,:cookies,:headers,:body,:status,:root
M=proc{|_,o,n|o.merge(n,&M)}
ENV['GEM_HOME'] = '/Users/phoenix/.ruby_versions/ruby-1.9.1-p129/lib/ruby/gems/1.9.1'
require 'rubygems'
require 'camping'
$: << ::File.expand_path(::File.dirname(__FILE__))
require 'bin/app'
App.create if App.respond_to? :create
run App
Удачного полёта!
на 00:23 0 коммент.
07 августа 2009
Делегирование методов контроллеров в Camping
Потребовалось мне недавно написать обёртку ко всем существующим ныне в приложении контроллерам, дабы их можно было вызывать через единую точку входа. Именно обёртку, поскольку всё к чертям переписывать не хотелось принципиально да и старый механизм работы мне бы самому пригодился. После пятнично-вечернего воскуривания сорцов Camping'а я это сделал (<ненависть>сорцы кемпинга - это лютое изнасилование мозга. Пусть этому вроде как и есть оправдание - '4K full of gags pocket framework', но так писать а тем более читать код нельзя</ненависть>). Вот вам примерчик - пусть есть контроллер, который просто возвращает завёрнутые в JSON свои параметры, и есть потребность вызвать его из другого контроллера:
def post(param1, param2)
return "{\"#{param1}\":\"#{param2}\"}"
end
end
controller_post_responce = App.post(:Controller, 'param1', 'param2').body
на 23:57 0 коммент.
02 августа 2009
Шаблон
Сменил шаблон блога на какой-то другой - теперь он резиновый и не уродует так код. Он мне не нравится, но я более-менее подправил цвета, чтобы глаз не резало.
на 23:48 2 коммент.
способы запуска Camping приложений
- традиционным camping app.rb
- напрямую app.rb или ruby app.rb
- через Passenger
- с использованием библиотеки Daemons
Второй требует, чтобы приложение само себя запустило, примерно таким кодом:
App::Models::Base.establish_connection :adapter => 'sqlite3', \
:database => "#{File.expand_path(File.dirname(__FILE__))}/../app.db"
App.create
end
if __FILE__ == $0
require 'mongrel/camping'
server = Mongrel::Camping::start(OPTIONS[:app_host], OPTIONS[:app_port], '/', App)
trap("KILL"){server.stop;exit}
server.acceptor.join
end
Третий способ тоже требует создания AR подключения и запуска приложения. Запуск из-под Passenger обнаруживается по наличию переменной окружения RACK_ENV. Об использовании этой переменной немного ниже. Ну а config.ru выглядит так:
require 'rubygems'
require 'rack'
$: << File.expand_path(File.dirname(__FILE__))
require 'bin/app'
run Rack::Adapter::Camping.new(App)
au BufWritePost * silent !test -f 'tmp/restart.txt' && touch 'tmp/restart.txt'
require 'rubygems'
require 'daemons'
Daemons.run( File.expand_path(File.dirname(__FILE__))+'/app.rb')
Ну и напоследок об окружениях. Идея RAILS_ENV хороша, почему бы и тут не сделать так же.
$logger = ((ENV['RACK_ENV'] || defined? Daemons )? \
# file-based logger for background execution and stdout for the rest
Logger.new("#{File.expand_path(File.dirname(__FILE__))}/../log/app.log", 10, 1024000) : \
Logger.new(STDOUT))
на 22:48 0 коммент.