<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Jaros&#322;aw Zabie&#322;&#322;o - BLOG: Tag rails</title>
    <link>http://blog.zabiello.com/articles/tag/rails</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>moje notatki, linki, komentarze</description>
    <item>
      <title>MagLev - wirtualna maszyna Smalltalka dla Rubiego</title>
      <description>&lt;p&gt;&lt;a href="http://gemstone.com"&gt;Gemstone&lt;/a&gt; to komercyjna, rozwijana od ponad 20 lat, bardzo szybka maszyna wirtualna dla j&#281;zyka &lt;a href="http://pl.wikipedia.org/wiki/Smalltalk"&gt;Smalltalk&lt;/a&gt;. Jest u&#380;ywana od  lat w zastosowaniach biznesowych, m.in. w instytucjach finansowych. W odr&#243;&#380;nieniu od innych Gemstone to co&#347; wi&#281;cej ni&#380; tylko maszyna wirtualna. Gemstone posiada wbudowany mechanizm bardzo wydajnego, transakcyjnego zapisu obiekt&#243;w, chodzi to obs&#322;ug&#281; obiekt&#243;w rz&#281;du setek i tysi&#281;cy miliard&#243;w (lub informacji o wielko&#347;ci 17 &lt;a href="http://pl.wikipedia.org/wiki/Petabajt"&gt;petabajt&#243;w&lt;/a&gt;). MagLev to smalltalkowy &lt;a href="http://www.gemstone.com/products/smalltalk/"&gt;GemStone &lt;span class="caps"&gt;S64 VM&lt;/span&gt;&lt;/a&gt; z dodanym bytecodem pozwalaj&#261;cym na uruchamianie &lt;strong&gt;Rubiego&lt;/strong&gt;. W r&#243;&#380;nych benchmarkach MagLev jest szybszy od Rubiego &lt;span class="caps"&gt;MRI&lt;/span&gt; od 7 do ponad 100 razy i osi&#261;ga &lt;a href="http://antoniocangiano.com/2008/06/05/maglev-handles-trees-like-a-monkey/"&gt;szybko&#347;&#263; zbli&#380;on&#261; do czystego C&lt;/a&gt;. Dodatkowo daje przezroczysty, wydajny zapis obiekt&#243;w Rubiego w spos&#243;b znacznie wygodniejszy od tego co oferuj&#261; relacyjne bazy danych. Czy&#380;by wkr&#243;tce mo&#380;na by&#322;o pokusi&#263; si&#281; o napisanie odpowiednika &lt;a href="http://zope.org/"&gt;Zope&lt;/a&gt; w Rubim pracuj&#261;cym pod wydajn&#261;, wirtualn&#261; maszyn&#261; Smalltalka?&lt;/p&gt;


	&lt;p&gt;Na razie projekt jest m&#322;ody. Maszyna wirtualna pewnie b&#281;dzie zamkni&#281;tym kodem, ale reszta powinna by&#263; wolna. Pierwsza prezentacja mo&#380;liwo&#347;ci Rubiego na MagLev odbyla si&#281; na niedawnej konferencji &lt;a href="http://www.infoq.com/news/2008/05/MagLevAtRailsConf"&gt;RailsConf 2008&lt;/a&gt;. Dost&#281;pne jest ju&#380; pierwsze wideo z prezentacji MagLev&amp;#8217;a (pozosta&#322;e dwie cz&#281;&#347;ci s&#261; w trakcie przygotowywania).&lt;/p&gt;


&lt;object width="400" height="302"&gt;    &lt;param name="allowfullscreen" value="true" /&gt;    &lt;param name="allowscriptaccess" value="always" /&gt;    &lt;param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=1147409&amp;amp;server=www.vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1" /&gt;    &lt;embed src="http://www.vimeo.com/moogaloop.swf?clip_id=1147409&amp;amp;server=www.vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=00ADEF&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="302"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a href="http://www.vimeo.com/1147409?pg=embed&amp;#38;sec=1147409"&gt;MagLev presentation at RailsConf 2008 &amp;#8211; part 1&lt;/a&gt; from &lt;a href="http://www.vimeo.com/montywilliams?pg=embed&amp;#38;sec=1147409"&gt;Monty Williams&lt;/a&gt; on &lt;a href="http://vimeo.com?pg=embed&amp;#38;sec=1147409"&gt;Vimeo&lt;/a&gt;.

	&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


	&lt;p&gt;Zobacz te&#380;:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.infoq.com/news/2008/04/maglev-gemstone-builds-ruby"&gt;MagLev: Gemstone builds Ruby runtime based on Smalltalk VM&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.infoq.com/interviews/bryant-ruby-maglev-gemstone"&gt;Avi Bryant on MagLev and GemStone&lt;/a&gt; &amp;#8211; b. ciekawy wywiad (video + transkrypcja)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.infoq.com/news/2008/05/MagLevAtRailsConf"&gt;GemStone Reveals Plans for MagLev Ruby VM at RailsConf 2008&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://antoniocangiano.com/2008/06/05/maglev-handles-trees-like-a-monkey/"&gt;MagLev handles trees like a monkey&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.avibryant.com/?p=16"&gt;Avi Bryant &amp;#8211; MagLev recap&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://antoniocangiano.com/2008/05/31/maglev-rocks/"&gt;MagLev rocks and the planning of the next Ruby shootout&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://collison.ie/blog/2008/06/maglev-and-language-implementation"&gt;MagLev and language implementation&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://railsconf.blip.tv/file/568689/"&gt;RailsConf 2007 &amp;#8211; Avi Bryant&lt;/a&gt; &amp;#8211; ciekawe wyst&#261;pienie Avi Branta przekonanego &#380;e zasadniczo Ruby prawie nie r&#243;&#380;ni si&#281; od Smalltalka, w zasadzie to ten sam j&#281;zyk i nie ma &#380;adnego powodu dla kt&#243;rego Ruby nie m&#243;g&#322;by by&#263; tak szybki jak Smalltalk (a Smalltalk jest 10x szybszy od Pythona&amp;#8230;)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.chadfowler.com/2008/6/5/maglev"&gt;Chad Fowler &amp;#8211; MagLev&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;</description>
      <pubDate>Sat, 14 Jun 2008 19:11:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:7408024c-7849-459e-b285-3e78c4c33579</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/06/14/maglev</link>
      <category>smalltalk</category>
      <category>ruby</category>
      <category>maglev</category>
      <category>rails</category>
      <category>vm</category>
      <category>gemstone</category>
    </item>
    <item>
      <title>Passenger bli&#380;ej - Rails, Rack i WSGI</title>
      <description>&lt;p&gt;Stworzony pierwotnie na u&#380;ytek Rails, aktualnie mod_passenger ju&#380; obs&#322;uguje nie tylko Rails ale tak&#380;e mas&#281; innych framework&#243;w u&#380;ywaj&#261;cych Rack&amp;#8217;a. W &lt;a href="http://tinyurl.com/6edmve"&gt;nowej dokumentacji&lt;/a&gt; wymienione s&#261; frameworki: &lt;a href="http://code.whytheluckystiff.net/camping"&gt;Camping&lt;/a&gt;, &lt;a href="http://halcyon.rubyforge.org/"&gt;Halcyon&lt;/a&gt;, &lt;a href="http://www.mackframework.com/"&gt;Mack&lt;/a&gt;, &lt;a href="http://merbivore.org/"&gt;Merb&lt;/a&gt;, &lt;a href="http://ramaze.net/"&gt;Ramaze&lt;/a&gt; i &lt;a href="http://sinatrarb.com/Home"&gt;Sinatra&lt;/a&gt;. W dokumentacji nie wymieniono jeszcze &amp;#8220;drugiej listy&amp;#8221;, zawieraj&#261;cej frameworki korzystaj&#261;ce z &lt;a href="http://www.wsgi.org/wsgi"&gt;&lt;span class="caps"&gt;WSGI&lt;/span&gt;&lt;/a&gt; i Pythona (np. &lt;a href="http://pylonshq.com/"&gt;Pylons&lt;/a&gt;, &lt;a href="http://djangoproject.com"&gt;Django&lt;/a&gt;, &lt;a href="http://turbogears.org/"&gt;TurboGears&lt;/a&gt; itp.). Chc&#261;c sprawdzi&#263; plotki wok&#243;&#322; tej sprawy, sprawdzi&#322;em, czy faktycznie mod_passenger pracuje nie tylko z Ruby, ale tak&#380;e z Pythonem. Sprawdzi&#322;em tak&#380;e jak to jest faktycznie z ob&#322;ug&#261; Rails i framework&#243;w na Rack&amp;#8217;u (tu sprawdzi&#322;em tylko Merba). Sprawdzi&#322;em te&#380; JRuby dla Rails i Merba.&lt;/p&gt;


	&lt;p&gt;Wszystkie testy by&#322;y wykonywane na laptopie MacBook Pro Core 2 Duo, 2.16GHZ, 4GB &lt;span class="caps"&gt;RAM&lt;/span&gt; (OSX 10.5.3 dla tego modelu widzi tylko 3GB) i dyskiem 200GB kr&#281;c&#261;cym si&#281; z szybko&#347;ci&#261; 7200 rpm. Ruby 1.8.6, Python 2.5.2, Apache 2.2.8 (mpm-prefork) by&#322;y instalowane z MacPort&#243;w. Passenger, mimo &#380;e instalowany &lt;a href="http://github.com/FooBarWidget/passenger/tree/master"&gt;ze &#378;r&#243;de&#322;&lt;/a&gt; w Apache&amp;#8217;u by&#322; wy&#347;wietlany jako &amp;#8220;Phusion_Passenger/1.1.0&amp;#8221; (by&#263; mo&#380;e wi&#281;c to nie jest jeszcze ta nowa wersja 2.0 o kt&#243;rej pisa&#322;em &lt;a href="http://blog.zabiello.com/articles/2008/06/04/passenger2-ruby-enterprise"&gt;wcze&#347;niej&lt;/a&gt;) Nie sprawdza&#322;em Linuksa, by&#263; mo&#380;e wyniki i wnioski b&#281;d&#261; wtedy inne.&lt;/p&gt;


	&lt;p&gt;Dla tych co chcieliby sami popr&#243;bowa&#263; podaj&#281; wpierw konfiguracj&#281; serwer&#243;w wirtualnych dla Apache&amp;#8217;a potrafi&#261;c&#261; unie&#347;&#263; razem: &lt;span class="caps"&gt;PHP&lt;/span&gt; (2.5.6), Rails (2.1), Merb (0.9.4 edge), i Django (edge).&lt;/p&gt;


	&lt;h2&gt;Konfiguracja Apache&amp;#8217;a  2.2.8&lt;/h2&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_apache "&gt;
# Ruby (Rails):
&amp;lt;VirtualHost *:80&amp;gt;     
  DocumentRoot &amp;quot;/opt/local/apache2/vhosts/rails_app/public&amp;quot;  
  ServerName rails_app
&amp;lt;/VirtualHost&amp;gt;

# Ruby (Merb):        
&amp;lt;VirtualHost *:80&amp;gt;  
  RailsAutoDetect off  
  DocumentRoot &amp;quot;/opt/local/apache2/vhosts/merb_app/public&amp;quot;    
  ServerName merb_app       
&amp;lt;/VirtualHost&amp;gt;

# Python (WSGI):
&amp;lt;VirtualHost *:80&amp;gt;          
  DocumentRoot &amp;quot;/opt/local/apache2/vhosts/wsgi_app/public&amp;quot;    
  ServerName wsgi_app
&amp;lt;/VirtualHost&amp;gt;      

# Django (mod_python)
&amp;lt;VirtualHost *:80&amp;gt;         
  DocumentRoot &amp;quot;/opt/local/apache2/vhosts/djangus/public&amp;quot;    
  ServerName django_modpython 
  &amp;lt;Location &amp;quot;/&amp;quot;&amp;gt;
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE djangus.settings
    PythonDebug On        
    PythonPath &amp;quot;['/opt/local/apache2/vhosts'] + sys.path&amp;quot;    
  &amp;lt;/Location&amp;gt;       
&amp;lt;/VirtualHost&amp;gt;   

# PHP:
&amp;lt;VirtualHost *:80&amp;gt;  
  RailsAutoDetect off  
  DocumentRoot &amp;quot;/opt/local/apache2/vhosts/php_app/public&amp;quot;        
  ServerName php_app   
&amp;lt;/VirtualHost&amp;gt;    &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Wszystkie aplikacje korzystaj&#261;ce z mod_passengera musz&#261; posiada&#263; folder &lt;code&gt;public&lt;/code&gt; i &lt;code&gt;tmp&lt;/code&gt;. Gdy do katalogu &lt;code&gt;tmp&lt;/code&gt; dorzucimy jakikolwiek (mo&#380;e by&#263; pusty) plik o nazwie &lt;code&gt;restart.txt&lt;/code&gt;, to przy nast&#281;pnym prze&#322;adowaniu przegl&#261;darki nast&#261;pi restart aplikacji.&lt;/p&gt;


	&lt;p&gt;We wszystkich przypadkach u&#380;y&#322;em dosy&#263; banalnego kodu polegaj&#261;cego na wy&#347;wietleniu &amp;#8220;Hello World!&amp;#8221;. Z wynik&#243;w programu &lt;code&gt;ab&lt;/code&gt; wyci&#261;&#322;em nieistotne informacje.&lt;/p&gt;


	&lt;h2&gt;Rails (2.1)&lt;/h2&gt;


	&lt;h3&gt;Rails 2.1 + mod_passenger 1.1.0&lt;/h3&gt;


	&lt;p&gt;Rails obs&#322;ugiwane s&#261; w Passengerze praktycznie bezobs&#322;ugowo. Wystarczy wkopiowa&#263; pliki na serwer i to wszystko.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;ab -n 1000 -c 1 http://rails/ 
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Total transferred:      582000 bytes
HTML transferred:       12000 bytes
Requests per second:    430.20 [#/sec] (mean)
Transfer rate:          244.35 [Kbytes/sec] received

ab -n 1000 -c 4 http://rails/
...
Concurrency Level:      4
Failed requests:        239
   (Connect: 0, Length: 239, Exceptions: 0)
Write errors:           0
Total transferred:      488073 bytes
HTML transferred:       9132 bytes
Requests per second:    520.75 [#/sec] (mean)
Transfer rate:          247.88 [Kbytes/sec] received&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; 

	&lt;p&gt;Szybko&#347;&#263; nie jest najgorsza, ale niepokoj&#261;ca jest du&#380;a lista b&#322;&#281;dnych request&#243;w w wypadku zapyta&#324; r&#243;wnoleg&#322;ych. Jak si&#281; dalej okazuje, ten problem dotyczy tak&#380;e ob&#322;ugi Rack jak i &lt;span class="caps"&gt;WSGI&lt;/span&gt;. Albo to jaka&#347; specyfika &lt;span class="caps"&gt;OSX&lt;/span&gt;, albo wcale nie jest tak dobrze ze stabilno&#347;ci&#261; mod_passengera dla r&#243;wnoleg&#322;ych zapyta&#324;. Trzeba by by&#322;o te&#380; zbada&#263;, czy ten efekt wyst&#281;puje tak&#380;e dla Linuksa. Zdziwi&#322;bym si&#281; gdyby tam by&#322;o podobnie skoro Dreamhost ju&#380; oferuje hosting z mod_rails&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Dla por&#243;wnania Rails u&#380;ywaj&#261;cy Mongrela, Thin oraz Ebb. Mo&#380;na by pokusi&#263; aby odpali&#263; Ebb i Thina na uniksowych socketach (Ebb te&#380; to ju&#380; potrafi!), ale wtedy musia&#322;bym zestawia&#263; klaster i uruchamia&#263; to przez proxy. Jak kto&#347; chce to niech si&#281; sam pobawi. Dla prostoty u&#380;y&#322;em port&#243;w &lt;span class="caps"&gt;TCP&lt;/span&gt;. Sprawdzi&#322;em te&#380; JRuby.&lt;/p&gt;


	&lt;h3&gt;Rails 2.1 + Ebb 0.2.0&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;ebb_rails -e production start

ab -n 1000 -c 1 http://127.0.0.1:3000/
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    488.95 [#/sec] (mean)

ab -n 1000 -c 4 http://127.0.0.1:3000/
..
Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    533.22 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; 

	&lt;p&gt;Szybko&#347;&#263; wi&#281;ksza od mod_passengera i co wa&#380;niejsze, zero jakichkolwiek b&#322;&#281;d&#243;w przy pracy r&#243;wnoleg&#322;ej.&lt;/p&gt;


	&lt;h3&gt;Rails 2.1 + Thin 0.8.1&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;thin start -e production              

ab -n 1000 -c 1 http://127.0.0.1:3000/
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    485.95 [#/sec] (mean)

ab -n 1000 -c 4 http://127.0.0.1:3000/
...              
Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    506.21 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Szybko&#347;&#263; troch&#281; mniejsza od Ebb, ale stabilno&#347;&#263; b. dobra.&lt;/p&gt;


	&lt;h3&gt;Rails 2.1 + Mongrel 1.1.5&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;script/server -e production

ab -n 1000 -c 1 http://127.0.0.1:3000/
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    373.74 [#/sec] (mean)

ab -n 1000 -c 4 http://127.0.0.1:3000/
...
Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    360.46 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Stabilno&#347;&#263; bez zarzutu, wydajno&#347;&#263; jednak mniejsza od serwer&#243;w pracuj&#261;cych asynchronicznie.&lt;/p&gt;


	&lt;h3&gt;Rails 2.1 + JRuby 1.1.2&lt;/h3&gt;


	&lt;p&gt;W wypadku JRuby trzeba go troch&#281; &amp;#8220;rozgrza&#263;&amp;#8221;. Pe&#322;na wydajno&#347;&#263; Javy pojawia si&#281; po jakim&#347; czasie pracy. Wynika to ze specyfiki i mo&#380;liwo&#347;&#263;i &lt;span class="caps"&gt;JVM&lt;/span&gt; kt&#243;ra dokonuje dynamicznych optymalizacji kodu w trakcie jego dzia&#322;ania (z tego powodu Java potrafi przewy&#380;szy&#263; wydajno&#347;ci&#261; C++). &amp;#8220;Dla rozgrzewki&amp;#8221; przepu&#347;ci&#322;em Rails przez 30 tys. request&#243;w co spowodowa&#322;o &#380;e pocz&#261;tkowych 137 req/s zrobi&#322;o si&#281; 257 req/s.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;jruby script/server -e production    

ab -n 1000 -c 1 http://127.0.0.1:3000/
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    200.48 [#/sec] (mean)

ab -n 1000 -c 4 http://127.0.0.1:3000/
...
Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    257.05 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;JRuby jest stabilny ale z wydajno&#347;ci&#261; dla Rails jeszcze jest troch&#281; do poprawienia. Dorzucenie opcji optymalizacyjnych, czyli odpalenie Rails przez&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;  
jruby -J-server -J-Djruby.compile.frameless=true script/server -e production&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;troch&#281; poprawi&#322;o wynik: 273 req/s, ale generalnie nie jest to wielka r&#243;&#380;nica. JRuby 1.1.x ju&#380; ma domy&#347;lnie pow&#322;&#261;czane optymalizacje.&lt;/p&gt;


	&lt;h3&gt;Rails &amp;#8211; wnioski&lt;/h3&gt;


	&lt;p&gt;mod_passenger dla Rails faktycznie jest wydajny, cho&#263; trzeba jeszcze by zbada&#263; dlaczego zwraca tyle b&#322;&#281;dnych request&#243;w dla r&#243;wnoleg&#322;ych zapyta&#324; i czy ten problem wyst&#281;puje te&#380; na Linuksie. Dlatego na razie najwydajniejszym i najstabilniejszym rozwi&#261;zaniem dla Rails wci&#261;&#380; pozostaje kombinacja nginx + proxy do ebb lub thin. mod_passenger kusi g&#322;&#243;wnie prostot&#261; konfiguracji (w&#322;a&#347;ciwie brakiem konfiguracji). No i chyba ja to testowa&#322;em dla mod_passengera w wersji 1.1, a nie 2.0 (przynajmniej taka si&#281; wy&#347;wietla w Apache).&lt;/p&gt;


	&lt;h2&gt;Merb 0.9.4 edge&lt;/h2&gt;


	&lt;h3&gt;Merb 0.9.4 edge + mod_passenger 1.1.0&lt;/h3&gt;


	&lt;p&gt;Aby u&#380;y&#263; frameworka Rack z Passengerem trzeba w katalogu projektu tworzy&#263; plik &lt;code&gt;config.ru&lt;/code&gt; zawieraj&#261;cy konfiguracj&#281; Rack&amp;#8217;a. W wypadku Merba b&#281;dzie to&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rubygems&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;merb-core&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;setup&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:merb_root&lt;/span&gt;   &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;.&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt;
                   &lt;span class="symbol"&gt;:environment&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;ENV&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;RACK_ENV&lt;/span&gt;&lt;span class="punct"&gt;'])&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;environment&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Config&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:environment&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;root&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Config&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:merb_root&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
&lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;BootLoader&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;run&lt;/span&gt;

&lt;span class="ident"&gt;run&lt;/span&gt; &lt;span class="constant"&gt;Merb&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Rack&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Application&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    762.62 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        247
   (Connect: 0, Length: 247, Exceptions: 0)
Write errors:           0
Requests per second:    985.15 [#/sec] (mean) &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Merb jest wci&#261;&#380; du&#380;o szybszy od Rails. Podobnie jak dla Rails, wiele r&#243;wnoleg&#322;ych zapyta&#324; nie zosta&#322;o poprawnie wykonanych. Na produkcyjne u&#380;ycie Passengera dla Merba jest jeszcze troch&#281; za wcze&#347;nie.&lt;/p&gt;


	&lt;h3&gt;Merb 0.9.4 edge + ebb 0.2.0&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;merb -e production -a ebb  
...                              
Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    1463.69 [#/sec] (mean)

Concurrency Level:      10
Failed requests:        0
Write errors:           0
Requests per second:    1560.60 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  

	&lt;p&gt;Merb na Ebb deklasuje wydajno&#347;ci&#261; wszystkie inne rozwi&#261;zania. Tylko czysty &lt;span class="caps"&gt;PHP&lt;/span&gt; jest w stanie mu dor&#243;wna&#263;, ale por&#243;wnywanie &lt;span class="caps"&gt;PHP&lt;/span&gt; z ca&#322;ym, z&#322;o&#380;onym frameworkiem Rubiego jest troch&#281; bez sensu. Z tego co m&#243;wi&#322; ostatnio (na kanale &lt;span class="caps"&gt;IRC&lt;/span&gt;) Ezra Zygmuntowicz, podpi&#281;cie Ebb na czystym Rack&amp;#8217;u, daje nawet &lt;strong&gt;7 tys req/s&lt;/strong&gt; i deklasuje (rzekomo) szybkiego &lt;span class="caps"&gt;PHP&lt;/span&gt;. Gadanie o wy&#380;szej wydajno&#347;ci &lt;span class="caps"&gt;PHP&lt;/span&gt; jest po prostu g&#322;upie. Mo&#380;na si&#281; za&#322;o&#380;y&#263;, &#380;e jakiekolwiek por&#243;wnanie frameworka naprzeciw frameworka, tj. Merba z Symfony czy Cake &lt;span class="caps"&gt;PHP&lt;/span&gt;, obna&#380;y bezlito&#347;nie s&#322;abo&#347;ci &lt;span class="caps"&gt;PHP&lt;/span&gt; &lt;a href="http://blog.zabiello.com/articles/2006/07/14/django-i-rails-bij%C4%85-php"&gt;tak, jak to zrobi&#322; Django&lt;/a&gt; w jednym ze starszych test&#243;w.&lt;/p&gt;


	&lt;h3&gt;Merb 0.9.4 edge + thin 0.8.1&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;merb -e production -a thin 
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    1147.78 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    1234.82 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  

	&lt;p&gt;Wydajno&#347;&#263; r&#243;wnie dobra, cho&#263; troch&#281; s&#322;absza od Ebb. Sporo wi&#281;cej od Rails i zero problem&#243;w ze stabilno&#347;ci&#261;.&lt;/p&gt;


	&lt;h3&gt;Merb 0.9.4 edge + mongrel 1.1.5&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;merb -e production -a mongrel
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    868.10 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    837.01 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;   

	&lt;p&gt;Mongrel jest wolniejszy od serwer&#243;w asynchronicznych ale i tak wyra&#378;nie szybszy od Rails.&lt;/p&gt;


	&lt;h3&gt;Merb 0.9.4 edge + JRuby 1.1.2&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt; 
jruby -S merb -e production 
...
Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    449.52 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    505.52 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Merb na &amp;#8220;rozgrzanym&amp;#8221; (30 tys. req) JRuby osi&#261;ga wydajno&#347;&#263; tak&#261; jak najszybsze rozwi&#261;zania dla Rails z u&#380;yciem asynchronicznego Ebb! To znaczy, &#380;e u&#380;ycie produkcyjne Merba w systemach Javy ma jak najbardziej sens.&lt;/p&gt;


	&lt;h2&gt;Passenger &amp;#38; &lt;span class="caps"&gt;WSGI&lt;/span&gt;&lt;/h2&gt;


	&lt;p&gt;Pora na przyjrzenie si&#281; temu jak mod_passenger daje sobie rad&#281; z Pythonem. W katalogu ze &#378;r&#243;d&#322;ami Passengera le&#380;y gotowa, prosta aplikacja &lt;span class="caps"&gt;WSGI&lt;/span&gt;. Dzieki dobrej dokumentacji Django, uda&#322;o mi si&#281; uruchomi&#263; ten framework pod Passengerem. Gorzej by&#322;o z Pylons. Nie uda&#322;o mi si&#281; stworzy&#263; poprawnego pliku passenger_wsgi.py, niezb&#281;dnego do tego aby Passenger uruchomi&#322; aplikacj&#281; &lt;span class="caps"&gt;WSGI&lt;/span&gt;.&lt;/p&gt;


	&lt;h3&gt;Django edge&lt;/h3&gt;


	&lt;p&gt;Django, mimo swych zalet, stosuje bardzo g&#322;upi&#261; polityk&#281; nie wypuszczania kolejnych wersji kodu. Dost&#281;pna na stronie wersa 0.96 jest stara i generalnie zaleca si&#281; aby u&#380;ywa&#263; nowsz&#261; wersj&#281;, kt&#243;ra istnieje tylko w repozytorium Subversion. Oparcie kodu produkcyjnego o wersj&#281; edge jest troch&#281; ryzykowne i szybko sprowadza si&#281; do z&#322;ej praktyki ci&#261;g&#322;ego  &#322;atania kodu.&lt;/p&gt;


	&lt;p&gt;W wypadku Django plik &lt;code&gt;passenger_wsgi.py&lt;/code&gt; zawiera kod:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;
&lt;span class="ident"&gt;sys&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;append&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;/bezwl/sciezka/do/nazwaprojektu&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt; 
&lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;environ&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;DJANGO_SETTINGS_MODULE&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;nazwaprojektu.settings&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;core&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;handlers&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;wsgi&lt;/span&gt;
&lt;span class="ident"&gt;application&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;core&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;handlers&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;wsgi&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;WSGIHandler&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;  ab -n 10000 -c 10            
  ...   
  apr_poll: The timeout specified has expired (70007)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Test pad&#322; po 9tys requestach. Dalej nie mo&#380;na by&#322;o uruchomi&#263; Django. Dopiero restart calego Apache&amp;#8217;a pom&#243;g&#322;. Dla ni&#380;szej ilo&#347;ci r&#243;wnoleg&#322;ych zapyta&#324; (ab -n 1000 -c 4) Django nie pad&#322;o, ale by&#322;o du&#380;o b&#322;&#281;dnych request&#243;w. Okaza&#322;o si&#281;, &#380;e problem wynika&#322; z r&#243;wnoczesnej obecno&#347;ci modu&#322;u mod_python i mod_passenger. Nie mo&#380;na ich razem w&#322;&#261;cza&#263;.&lt;/p&gt;


	&lt;p&gt;Usuni&#281;cie mod_passengera i zostawienie samego mod_pythona pomog&#322;o. (Albo jest jaki&#347; konflikt mi&#281;dzy nimi, albo (co bardziej jest prawdopodobne) trzeba poczeka&#263; na opcj&#281; wy&#322;&#261;czaj&#261;c&#261; passengera dla serwera wirtualnego u&#380;ywaj&#261;cego mod_pythona. Dla Rails i Rack s&#261; takie opcje (RailsAutoDetect, RackAutoDetect), dla &lt;span class="caps"&gt;WSGI&lt;/span&gt; nie mog&#322;em nic takiego znale&#378;&#263; w kodzie &#378;r&#243;d&#322;owym. Modu&#322;u mod_wsgi nie sprawdza&#322;em, bo nie by&#322;o go dost&#281;pnego w portach &lt;span class="caps"&gt;OSX&lt;/span&gt;.)&lt;/p&gt;


	&lt;p&gt;Po zablokowaniu mod_passenger&amp;#8217;a tym razem mod_python nie zwraca&#322; &#380;adnego b&#322;&#281;dnego requestu.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    934.87 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        0
Write errors:           0
Requests per second:    1240.26 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Nie jest &#378;le. Django jest tu wyra&#378;nie szybsze od Rails (co nikogo nie dziwi), ale jest wolniejsze od Merba, co dla mi&#322;o&#347;nik&#243;w Pythona mo&#380;e by&#263; przykr&#261; niespodziank&#261;. Wi&#281;kszo&#347;&#263; krytyki Rubiego oparta jest na krytyce (s&#322;abszej) wydajno&#347;ci Rails&#243;w. Okazuje si&#281;, &#380;e winny nie jest Ruby, ale s&#322;abo zoptymalizowany Rails. Merb jest dowodem na to, &#380;e mo&#380;na napisa&#263; w Rubim framework, kt&#243;ry nie tylko b&#281;dzie partnerem dla rozwi&#261;zan Pythona, ale nawet potrafi je przewy&#380;sza&#263; wydajno&#347;ciowo.&lt;/p&gt;


	&lt;p&gt;Zobaczmy jak wypadnie &lt;strong&gt;mod_passenger&lt;/strong&gt;.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;Concurrency Level:      1
Failed requests:        0
Write errors:           0
Requests per second:    904.60 [#/sec] (mean)

Concurrency Level:      4
Failed requests:        240
   (Connect: 0, Length: 240, Exceptions: 0)
Write errors:           0
Requests per second:    497.51 [#/sec] (mean)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;W pracy jednoprocesowej nie mo&#380;na mie&#263; zastrze&#380;e&#324;. Szybko&#347;&#263; jest niez&#322;a. Niestety praca r&#243;wnoleg&#322;a to pora&#380;ka. Du&#380;o request&#243;w nie zosta&#322;o obs&#322;u&#380;onych. Gorzej, za drugim razem (tylko dla 4 rownoleg&#322;ych zapyta&#324;) Django kompletnie si&#281; za&#322;ama&#322;o i zwr&#243;ci&#322;o wyj&#261;tek &amp;#8220;apr_poll: The timeout specified has expired (70007)&amp;#8221;. Nie mo&#380;na by&#322;o go d&#322;u&#380;ej u&#380;ywa&#263;. Wymagany by&#322; restart Apache&amp;#8217;a.&lt;/p&gt;


	&lt;p&gt;Aby sprawdzi&#263; czy to tylko problem Django czy og&#243;lnie implementacji &lt;span class="caps"&gt;WSGI&lt;/span&gt; dla mod_passengera, uruchomi&#322;em test na prostej aplikacji &lt;span class="caps"&gt;WSGI&lt;/span&gt;. Niestety sytuacja jest ta sama.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Wniosek&lt;/strong&gt;: mod_passenger dla Pythona wymaga dopracowania pracy r&#243;wnoleg&#322;ej. Jeszcze za wcze&#347;nie aby go u&#380;ywa&#263; z Pythonem. Ale z drugiej strony uruchomi&#322;em mod_passengera z &lt;span class="caps"&gt;WSGI&lt;/span&gt;  troch&#281; przedwcze&#347;nie. Nie ma przecie&#380; w manualu ani jednego zdania o tym, &#380;e Passenger dzia&#322;a z &lt;span class="caps"&gt;WSGI&lt;/span&gt;. Opar&#322;em si&#281; tylko na pog&#322;oskach i wygrzeba&#322;em t&#261; opcj&#281; ze &#378;r&#243;de&#322;. Wi&#281;c jeszcze wszystko mo&#380;e si&#281; tu zmieni&#263;. To samo dotyczy Rack&amp;#8217;a. Tw&#243;rcy musz&#261; przyjrze&#263; si&#281; problemom zwi&#261;zanym z obs&#322;ug&#261; r&#243;wnoleg&#322;ych zapyta&#324;.&lt;/p&gt;


	&lt;h3&gt;Update&lt;/h3&gt;


	&lt;p&gt;Jednak dobrze si&#281; domy&#347;la&#322;em, Apache nie oszukiwa&#322;. W tek&#347;cie testowa&#322;em starszego Passengera 1.1. Tak&#380;e nie by&#322; to Ruby Enterprise. &lt;span class="caps"&gt;NOWY&lt;/span&gt; Passenger 2.0RC1 oraz Ruby Enterprise zosta&#322; dopiero niedawno &lt;a href="http://blog.phusion.nl/2008/06/09/phusion-passenger-20-rc-1-and-ruby-enterprise-edition-released/"&gt;opublikowany&lt;/a&gt;. Co ciekawe, dodano obs&#322;ug&#281; Apache &lt;span class="caps"&gt;MPM&lt;/span&gt; &lt;strong&gt;Worker&lt;/strong&gt; a nie &lt;span class="caps"&gt;MPM&lt;/span&gt; Prefork, co dodatkowo zmniejsza zu&#380;ycie pami&#281;ci. Niestety Passenger 2.0RC1 jest na razie dost&#281;pny tylko w wersji na Linuksa.&lt;/p&gt;</description>
      <pubDate>Sat, 07 Jun 2008 15:24:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:1dc84c82-1634-41dd-9aa1-9c744a876dff</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/06/07/passenger-rack-wsgi</link>
      <category>rails</category>
      <category>ruby</category>
      <category>python</category>
      <category>django</category>
      <category>merb</category>
      <category>apache</category>
      <category>benchmark</category>
      <category>jruby</category>
    </item>
    <item>
      <title>JRuby Rack</title>
      <description>&lt;p&gt;&lt;a href="http://wiki.jruby.org/wiki/JRuby_Rack"&gt;JRuby Rack&lt;/a&gt; pozwala na wygodne uruchamianie pod &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; zar&#243;wno Rails, Merb jak i ka&#380;dy inny framework korzystaj&#261;cy z Rack. JRuby Rack zosta&#322;&#160;w&#322;aczony do gemu &lt;a href="http://wiki.jruby.org/wiki/Warbler"&gt;Warbler&lt;/a&gt; 0.9.9 u&#380;ywanego do budowania pliku &lt;span class="caps"&gt;WAR&lt;/span&gt; dla Rails 2.x. Vide &lt;a href="http://blog.nicksieger.com/articles/2008/05/08/introducing-jruby-rack"&gt;Introducing JRuby-Rack&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 04 Jun 2008 03:56:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:3adec824-f2d7-4f88-b01a-4283d5d6bada</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/06/04/jruby-rack</link>
      <category>jruby</category>
      <category>rack</category>
      <category>rails</category>
      <category>merb</category>
    </item>
    <item>
      <title>Sprz&#261;tanie po PHP czyli Passenger 2.0 i Ruby Enterprise 1.0</title>
      <description>&lt;p&gt;Sta&#322;o si&#281;! &lt;a href="http://www.phusion.nl/"&gt;Tw&#243;rcy&lt;/a&gt; &#347;wietnego modu&#322;u Apache&amp;#8217;a &amp;#8211; &lt;a href="http://www.modrails.com/"&gt;mod_rails&lt;/a&gt; &amp;#8211; zmieniaj&#261; jego nazw&#281; na &lt;strong&gt;mod_passenger&lt;/strong&gt;, bo mod_rails nie jest ju&#380; wi&#281;cej modu&#322;em tylko dla &lt;a href="http://rubyonrails.pl"&gt;Rails&lt;/a&gt;. W nowej wersji 2.0 (ktora ma wyj&#347;&#263;&#160;&lt;a href="http://groups.google.com/group/phusion-passenger/browse_thread/thread/a2b63650c1b9394"&gt;na dniach&lt;/a&gt;) dodano pe&#322;ne wsparcie dla &lt;a href="http://blog.zabiello.com/articles/2008/03/04/frameworki-rubiego-rack-wsgi"&gt;Rack&lt;/a&gt; i tym samym mod_passenger 2.0 obs&#322;uguje wszystkie pozosta&#322;e frameworki u&#380;ywaj&#261;ce Rack&amp;#8217;a (ze &#347;wietnym &lt;a href="http://merbivore.com"&gt;Merbem&lt;/a&gt; w&#322;&#261;cznie).&lt;/p&gt;


	&lt;p&gt;Drugim, ciekawym projektem firmy &lt;a href="http://www.phusion.nl/"&gt;Phusion&lt;/a&gt; jest &lt;a href="http://www.rubyenterpriseedition.com/"&gt;Ruby Enterprise&lt;/a&gt; (wersja 1.0 ma by&#263; dost&#281;pna lada dzie&#324; razem z Passenger 2.0). Jest to podrasowana wersja interpretera Rubiego (MRI) powoduj&#261;ca nie tylko przy&#347;pieszenie ale tak&#380;e znaczne zmniejszenie zu&#380;ycia pami&#281;ci &lt;span class="caps"&gt;RAM&lt;/span&gt; (dodano technik&#281; copy-on-write do garbage collectora interpretera &lt;span class="caps"&gt;MRI&lt;/span&gt;, dok&#322;adniej opisano to na &lt;a href="https://dl.getdropbox.com/u/26205/railsconf.pdf"&gt;slajdach&lt;/a&gt;). Wg tego co twierdz&#261; ludzie z Phusion, uzyskano zmniejszenie o 33% zu&#380;ycia pami&#281;ci przez Rails. To bardzo dobra wiadomo&#347;&#263;, bo pami&#281;&#263; mimo, &#380;e jest generalnie tania, nie jest tania w ofertach hostingowych &lt;span class="caps"&gt;VPS&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Passenger wprowadza now&#261; jako&#347;&#263; dla framework&#243;w Rubiego. Coraz wi&#281;cej firm hostingowych to docenia i przechodzi na Passenger&amp;#8217;a (z tych bardziej znanych, &lt;a href="http://blog.dreamhost.com/2008/05/13/passenger-for-ruby-on-rails/"&gt;Dreamhost ju&#380; tego u&#380;ywa&lt;/a&gt;). Sam modu&#322;&#160;mod_passenger jest nie tylko trywialny w u&#380;yciu, jest te&#380; bardzo szybki i stabilny. Chyba nadchodz&#261; ci&#281;&#380;kie chwile dla tych, co trzymali si&#281; &lt;span class="caps"&gt;PHP&lt;/span&gt; g&#322;&#243;wnie z powodu jego taniego hostingu i prostoty uruchomiania serwerze. Rails i Merb mog&#261; wkr&#243;tce troch&#281; pozamiata&#263; po &lt;span class="caps"&gt;PHP&lt;/span&gt;. :)&lt;/p&gt;


	&lt;p&gt;Szybko&#347;&#263; mod_passenger&amp;#8217;a robi wra&#380;enie. Bije wydajno&#347;ci&#261; kombinacj&#281; &lt;a href="http://nginx.net/"&gt;Nginx&lt;/a&gt; + asynchroniczny &lt;a href="http://code.macournoyer.com/thin/"&gt;Thin&lt;/a&gt; u&#380;ywaj&#261;cy szybkich, uniksowych socket&#243;w. Jest te&#380; szybszy od komercyjnego &lt;a href="http://litespeedtech.com/"&gt;Litespeed&amp;#8217;a&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://blog.zabiello.com/images/passenger_vs_thin.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://blog.zabiello.com/images/passenger_vs_litespeed.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Co ciekawe, mod_passenger obs&#322;uguje interfejs &lt;strong&gt;&lt;span class="caps"&gt;WSGI&lt;/span&gt; do Pythona&lt;/strong&gt;! Jeden modu&#322; pozwoli wi&#281;c na odpalanie Rails, Merb&amp;#8217;a i Django r&#243;wnocze&#347;nie. Ma&#322;o tego, je&#347;li mod_passenger dla Pythona b&#281;dzie dzia&#322;a&#322; tak sprawnie jak dla Rails, to b&#281;dziemy mie&#263; trywialne prze&#322;adowywanie aplikacji Django bez konieczno&#347;ci restartu ca&#322;ego Apache&amp;#8217;a.&lt;/p&gt;


	&lt;p&gt;Vide:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.railsjedi.com/posts/52-The-Holy-Grail-for-Rails-Deployment"&gt;The Holy Grail for Rails Deployment&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.rubyinside.com/28_mod_rails_and_passenger_resources-899.html"&gt;28 mod_rails / Passenger Resources To Help You Deploy Rails Applications Faster&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://github.com/FooBarWidget/passenger/tree/master"&gt;Passenger 2.0 na GitHub.com&lt;/a&gt; dla tych, co chc&#261; ju&#380; teraz zainstalowa&#263; mod_passenger 2.0 (ja ju&#380; to zainstalowa&#322;em)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;Update&lt;/h3&gt;


	&lt;p&gt;&lt;em&gt;2008-06-25&lt;/em&gt;&lt;/p&gt;


&lt;object width="400" height="225"&gt;    &lt;param name="allowfullscreen" value="true" /&gt;    &lt;param name="allowscriptaccess" value="always" /&gt;    &lt;param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=1198020&amp;amp;server=www.vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;    &lt;embed src="http://www.vimeo.com/moogaloop.swf?clip_id=1198020&amp;amp;server=www.vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="225"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a href="http://www.vimeo.com/1198020?pg=embed&amp;#38;sec=1198020"&gt;Phusion Passenger 2.0 and Ruby Enterprise Edition&lt;/a&gt; from &lt;a href="http://www.vimeo.com/user519957?pg=embed&amp;#38;sec=1198020"&gt;Carl Youngblood&lt;/a&gt; on &lt;a href="http://vimeo.com?pg=embed&amp;#38;sec=1198020"&gt;Vimeo&lt;/a&gt;

	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://blog.dmilith.pl/2008/06/25/ruby-enterprise-edition-32bit-na-debianie-etch-64bit"&gt;Ruby Enterprise Edition 32bit na debianie etch 64bit?&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;</description>
      <pubDate>Wed, 04 Jun 2008 01:40:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:77d6b3df-2b86-4365-b5de-d4fd9b153ecc</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/06/04/passenger2-ruby-enterprise</link>
      <category>mod_rails</category>
      <category>ruby</category>
      <category>rails</category>
      <category>merb</category>
      <category>rack</category>
      <category>apache</category>
      <category>php</category>
      <category>django</category>
      <category>python</category>
    </item>
    <item>
      <title>Rails 2.1</title>
      <description>&lt;p&gt;No to mamy w ko&#324;cu oficjalne wydanie &lt;a href="http://weblog.rubyonrails.org/2008/6/1/rails-2-1-time-zones-dirty-caching-gem-dependencies-caching-etc"&gt;Rails 2.1&lt;/a&gt;! Instalacja jest ju&#380; te&#380; dost&#281;pna przez RubyGems.&lt;/p&gt;</description>
      <pubDate>Sun, 01 Jun 2008 12:20:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:9e528d4b-4c01-4c49-956e-11e2939b3688</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/06/01/rails-2-1</link>
      <category>rails</category>
    </item>
    <item>
      <title>Ruby on Rails w Irlandii</title>
      <description>&lt;p&gt;Tak pomy&#347;la&#322;em, &#380;e mo&#380;e wrzuc&#281; info tutaj, bo troch&#281; os&#243;b z bran&#380;y czyta ten blog. Ot&#243;&#380; w mojej firmie szukamy &lt;a href="http://www.rubyonrails.pl/forum/viewtopic.php?pid=5546#p5546"&gt;jakiego&#347; railsowca do zespo&#322;u&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Thu, 29 May 2008 21:21:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:0d50f135-226a-4690-9cc8-bd144dee6026</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/05/29/ruby-on-rails-w-irlandii</link>
      <category>rails</category>
      <category>ruby</category>
      <category>ireland</category>
      <category>praca</category>
    </item>
    <item>
      <title>Agile 3 - jednak wyjdzie</title>
      <description>&lt;p&gt;Mimo, &#380;e wcze&#347;niej &lt;span class="caps"&gt;DHH&lt;/span&gt; niezbyt entuzjastycznie wypowiada&#322; si&#281; na temat pisania kolejnej edycji bestseleru &lt;a href="http://helion.pl/ksiazki/agilep.htm"&gt;Agile Web Development in Rails&lt;/a&gt;, to jednak ugi&#261;&#322; si&#281; pod ci&#281;&#380;arem oczekiwa&#324; i trzecie wydanie b&#281;dzie! Ci, co nie chc&#261; czeka&#263;, mog&#261; ju&#380; teraz kupi&#263; &lt;a href="http://pragprog.com/titles/rails3/agile-web-development-with-rails-third-edition"&gt;&lt;span class="caps"&gt;PDF&lt;/span&gt; z wersj&#261;&#160;beta ksi&#261;&#380;ki&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Je&#347;li autorzy b&#281;d&#261; jak zwykle opisywa&#263; wersj&#281; edge, to ksi&#261;&#380;ka powinna opisywa&#263; &lt;a href="http://weblog.rubyonrails.org/2008/4/30/rails-2-1-release-candidate-is-imminent"&gt;maj&#261;cy wkr&#243;tce wyj&#347;&#263; Rails 2.1&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Dobr&#261; wie&#347;ci&#261; jest te&#380; to, &#380;e Ezra Zygmuntowicz, tw&#243;rca konkurencyjnego &lt;a href="http://merbivore.com/"&gt;Merba&lt;/a&gt;) postanowi&#322; ostatnio po&#347;wi&#281;ci&#263; troch&#281; czasu aby &lt;a href="http://brainspl.at/articles/2008/04/25/hey-rails-nice-rack"&gt;ulepszy&#263; kod Rails&#243;w&lt;/a&gt;. Najwyra&#378;niej oba developerzy obu framework&#243;w si&#281; nie zwalczaj&#261; ale chc&#261; ze sob&#261; wsp&#243;&#322;pracowa&#263;. Ezra &lt;a href="http://brainspl.at/articles/2008/04/18/deferred-requests-with-merb-ebb-and-thin"&gt;doda&#322; ostatnio&lt;/a&gt; ciekawy mechanizm do obs&#322;ugi asynchronicznych adapter&#243;w Thin i Ebb, pozwalaj&#261;cy na tworzenie oddzielnego w&#261;tku w wypadku gdy zapytanie jest d&#322;ugie (aby nie blokowa&#322;a si&#281; asynchroniczna p&#281;tla).&lt;/p&gt;</description>
      <pubDate>Thu, 01 May 2008 20:15:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:2fd10714-776e-4b9a-aa15-6483d939307f</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/05/01/agile3</link>
      <category>rails</category>
      <category>merb</category>
    </item>
    <item>
      <title>Passenger mod_rails</title>
      <description>&lt;p&gt;Cho&#263; sam &lt;a href="http://rubyonrails.pl"&gt;Rails&lt;/a&gt; jest intuicyjny i prosty w u&#380;yciu, to ju&#380; spos&#243;b u&#380;ycia go na serwerze produkcyjnym (gdzie liczy si&#281; g&#322;&#243;wnie szybko&#347;&#263;&#160;i stabilno&#347;&#263;) nie jest takie oczywiste z powodu istnienia wielu, alternatywnych rozwi&#261;za&#324;. Powsta&#322;y niedawno modu&#322; dla Apache &amp;#8211; &lt;a href="http://www.modrails.com"&gt;mod_rails&lt;/a&gt; &amp;#8211; mo&#380;e wszystko zmieni&#263;. Dzi&#281;ki niemu uruchomienie Rails na serwerze staje si&#281;&#160;praktycznie tak samo trywialne jak w przypadku &lt;span class="caps"&gt;PHP&lt;/span&gt; i modu&#322;u mod_php!&lt;/p&gt;


	&lt;p&gt;Musz&#281; przyzna&#263;, &#380;e pocz&#261;tkowo by&#322;em dosy&#263; sceptycznie nastawiony do pomys&#322;u mod_rails. Przede wszystkim, dziwnym wydawa&#322;o si&#281; tworzy&#263; modu&#322; do Apache&amp;#8217;a dla frameworka, czyli w sumie aplikacji, a nie dla samego j&#281;zyka Ruby. Niestety, istniej&#261;cy od jakiego&#347; czasu mod_ruby by&#322; niedopracowany i krytykowany do tego stopnia &#380;e u&#380;ycie go do Rails jest po prostu niezalecane. Dlatego od samego pocz&#261;tku, gdy pojawi&#322; si&#281; Rails, promowano inne rozwi&#261;zanie (oparte na FastCGI). Pierwsze wydanie &amp;#8220;Agile Web Development with Rails&amp;#8221; jeszcze to promowa&#322;o. W drugim wydaniu (wydanym r&#243;wnie&#380; &lt;a href="http://helion.pl/ksiazki/agilep.htm"&gt;po polsku&lt;/a&gt;) autorzy przyznali &#380;e to rozwi&#261;zanie nie by&#322;o wolne od szerego problem&#243;w. Na szcz&#281;&#347;cie pojawi&#322; si&#281; Mongrel i bardzo szybko kombinacja szybkiego serwera &lt;span class="caps"&gt;HTTP&lt;/span&gt; z przodu + load balancing do klastera z mongreli sta&#322;a si&#281; g&#322;&#243;wn&#261; metod&#261; u&#380;ywania Rails na serwerze produkcyjnym. I cho&#263; p&#243;&#378;niej pojawi&#322;y si&#281; jeszcze rozwi&#261;zania asynchroniczne (Swiftiply i evented_mongrel, Thin, Ebb), to  zasadniczo niewiele wnosi&#322;y do rozwi&#261;zania standardowego poza troch&#281;&#160;wi&#281;ksz&#261; szybko&#347;ci&#261; i innym (w&#322;a&#347;nie asynchronicznym) typem pracy.&lt;/p&gt;


	&lt;p&gt;Do tej pory sympatycy Ruby on Rails troch&#281; sm&#281;tnie pogl&#261;dali na prostot&#281; uruchamiania aplikacji &amp;#8220;tego paskudnego pehapa&amp;#8221; za pomoc&#261; modu&#322;u mod_php. To dzi&#281;ki niemu &lt;span class="caps"&gt;PHP&lt;/span&gt; zdoby&#322; swoj&#261; popularno&#347;&#263;. Stworzenie prostej strony webowej sta&#322;o si&#281; banalnie proste i nie wymaga&#322;o dodatkowej wiedzy o load balancingu, ustawianiu buforowania, sposobie restartu klastera mongreli itp. Po prostu wrzucam plik i dzia&#322;a. Nawet sam &lt;span class="caps"&gt;DHH&lt;/span&gt; &lt;a href="http://www.loudthinking.com/posts/23-the-immediacy-of-php"&gt;zacz&#261;&#322; ostatnio wzdycha&#263;&lt;/a&gt; za tak&#261; prostot&#261; uruchamiania aplikacji.&lt;/p&gt;


	&lt;p&gt;Stworzony mod_rails ma ambicj&#281; aby uruchomienie Rails&#243;w by&#322;o tak proste jak to tylko mo&#380;liwe. Z tego co mog&#322;em sprawdzi&#263;, faktycznie dzia&#322;a to &#347;wietnie. Praktycznie nie jest wymagana &#380;adna konfiguracja. Wystarczy raz ustawi&#263; Apache&amp;#8217;a i mo&#380;na skupi&#263; si&#281; na budowaniu aplikacji. Domy&#347;lnie mod_rails uruchamia Rails w trybie produkcyjnym wi&#281;c zmiana kodu wymaga prze&#322;adowanie aplikacji. Jednak&#380;e ca&#322;a taka operacja sprowadza si&#281; do stworzenia pustego pliku &lt;code&gt;restart.txt&lt;/code&gt; w podkatalogu tmp. Gdy Apache znajdzie taki plik, b&#322;yskawicznie prze&#322;adowuje pliki Rubiego i usuwa plik. Nie trzeba te&#380; zastanawia&#263; si&#281; jak wyklucz&#261;&#263;&#160;przetwarzanie plik&#243;w statycznych i tworzonych przez mechanizm cache w RoR, mod_rails robi to automatycznie. Do tego zapewniona jest tak&#380;e &#322;adna obs&#322;uga b&#322;&#281;d&#243;w. Po prostu wygl&#261;da to rewelacyjnie.&lt;/p&gt;


	&lt;p&gt;Jak z wydajno&#347;ci&#261;? Jest ca&#322;kiem nie&#378;le. Autorzy twierdz&#261;, &#380;e mod_rails jest troch&#281; szybszy od thin&amp;#8217;a. Mnie wysz&#322;o troch&#281; odwrotnie, ale te&#380; nie robi&#322;em zbyt drobiazgowych por&#243;wna&#324;. Nawet je&#347;li klaster serwer&#243;w thin czy ebb pracuje troch&#281; wydajniej, to pokusa prostoty i wygody u&#380;ycia mod_rails jest trudna do odparcia. Szkoda tylko, &#380;e mod_rails, jak sama nazwa wskazuje, pracuje tylko z Ruby on Rails. Dobrze by by&#322;o, &#380;eby p&#243;&#378;niej powsta&#322;a podobna obs&#322;uga dla &lt;a href="http://merbivore.com/"&gt;Merb&amp;#8217;a&lt;/a&gt; (Cho&#263; Rails si&#281; tak&#380;e rozwija, Merb wci&#261;&#380; go mocno wyprzedza wydajno&#347;ciowo. Tak z prostych test&#243;w mi wysz&#322;o, &#380;e potrafi by&#263; szybszy nawet 2-3 razy). Nie mo&#380;na jednak autorom mod_rails mie&#263; przecie&#380; za z&#322;e, &#380;e po&#347;wi&#281;cili si&#281; najpopularniejszemu frameworkowi.&lt;/p&gt;


	&lt;p&gt;Passenger mod_rails to nie ostatnie s&#322;owo w sprawie deployingu Rails&#243;w. Podobn&#261; prostot&#261; charakteryzuje si&#281; JRuby on Rails, ale o tym nast&#281;pnym razem.&lt;/p&gt;</description>
      <pubDate>Sat, 19 Apr 2008 05:31:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:9896a167-4e71-4fe5-863a-aa17527bc110</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/04/19/passenger-mod_rails</link>
      <category>mod_rails</category>
      <category>ruby</category>
      <category>rails</category>
      <category>apache</category>
    </item>
    <item>
      <title>GitHub oficjalnie</title>
      <description>&lt;p&gt;Po okresie pilota&#380;owym, &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt; wystartowa&#322; &lt;a href="http://github.com/blog/40-we-launched"&gt;oficjalnie&lt;/a&gt;. GitHub udost&#281;pnia wygodne zarz&#261;dzanie projektami korzystaj&#261;cymi z &lt;a href="http://git.or.cz/"&gt;Git&amp;#8217;a&lt;/a&gt; &amp;#8211; rozproszonego systemu wersjonowania kodu. Poza opcjami komercyjnymi jest dost&#281;pne &lt;em&gt;darmowe&lt;/em&gt; konto dla projekt&#243;w open source (tzn. nie mo&#380;na w nim trzyma&#263; prywatnych, zamkni&#281;tych repozytori&#243;w, ale poza tym jest w wystarczaj&#261;co funkcjonalne). Na Git&amp;#8217;a migruje coraz wi&#281;cej projekt&#243;w. Poza &lt;a href="http://www.merbivore.com/"&gt;Merbem&lt;/a&gt; i (&lt;a href="http://weblog.rubyonrails.org/2008/4/2/rails-is-moving-from-svn-to-git"&gt;wkr&#243;tce&lt;/a&gt;) &lt;a href="http://rubyonrails.org"&gt;Railsami&lt;/a&gt;, na GitHuba przenios&#322;y si&#281; ju&#380;: &lt;a href="https://github.com/nex3/haml/tree"&gt;Haml&lt;/a&gt;, &lt;a href="https://github.com/ry/ebb/tree"&gt;Ebb&lt;/a&gt;, &lt;a href="https://github.com/wycats/jspec/tree"&gt;JSpec&lt;/a&gt;, &lt;a href="http://github.com/jamis/capistrano/tree/master"&gt;Capistrano&lt;/a&gt;, &lt;a href="https://github.com/sam/dm-core/tree"&gt;DataMapper&lt;/a&gt; itd.&lt;/p&gt;</description>
      <pubDate>Fri, 11 Apr 2008 01:38:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:2e77f8d5-21d8-49cb-86cc-c064818b75e6</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/04/11/github-oficjalnie</link>
      <category>git</category>
      <category>rails</category>
      <category>merb</category>
    </item>
    <item>
      <title>Nadchodzi Rails 2.1</title>
      <description>&lt;p&gt;Jest bardzo bardzo niewiele ksi&#261;&#380;ek opisuj&#261;cych aktualny stan Rails&#243;w 2.0.2 a ju&#380; &lt;a href="http://weblog.rubyonrails.org/2008/4/1/a-taste-of-what-s-coming-in-rails-2-1"&gt;szykuje si&#281; kolejna wersja &amp;#8211; 2.1&lt;/a&gt; (nawet &lt;a href="http://www.rubyonrails.pl/ksiazki"&gt;The Rails Way&lt;/a&gt; nie opisuje 2.0.2, ale tylko troch&#281;&#160;z wersji edge, sprzed wydania 2.0) Jak&#261; ksi&#261;&#380;k&#281; nie zacz&#281;to by pisa&#263;, staje si&#281; szybko nieaktualna.  Co za czasy&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Zmian jest ca&#322;kiem sporo, do wa&#380;niejszych nale&#380;&#261; r&#243;&#380;ne poprawki w Active Record. Np. w ko&#324;cu ma by&#263; mo&#380;liwa  &lt;a href="http://ryandaigle.com/articles/2008/3/31/what-s-new-in-edge-rails-dirty-objects"&gt;selektywna aktualizacja wybranych kolumn&lt;/a&gt; (do tej pory AR, podczas zmiany jedneego atrybutu aktualizowa&#322; je wszyskie w bazie) Co prawda t&#261; funkcjonalno&#347;&#263; od dawna maj&#261; &lt;a href="http://datamapper.org/docs/create_and_destroy.html"&gt;DataMapper&lt;/a&gt; i Sequel, ale dobrze &#380;e AR si&#281; wko&#324;cu tu obudzi&#322;.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;article&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:first&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;changed?&lt;/span&gt;  &lt;span class="comment"&gt;#=&amp;gt; false&lt;/span&gt;

&lt;span class="comment"&gt;# Zmiany poszczeg&#243;lnych atrybut&#243;w mo&#380;liwe jest za &lt;/span&gt;
&lt;span class="comment"&gt;# pomoc&#261; akcesora attr_name_changed?&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title&lt;/span&gt;  &lt;span class="comment"&gt;#=&amp;gt; &amp;quot;Title&amp;quot;&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;New Title&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title_changed?&lt;/span&gt; &lt;span class="comment"&gt;#=&amp;gt; true&lt;/span&gt;

&lt;span class="comment"&gt;# Jest te&#380; dost&#281;p do poprzedniej warto&#347;ci atrybutu &lt;/span&gt;
&lt;span class="comment"&gt;# zapomoc&#261; akcesora attr_name_was&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title_was&lt;/span&gt;  &lt;span class="comment"&gt;#=&amp;gt; &amp;quot;Title&amp;quot;&lt;/span&gt;

&lt;span class="comment"&gt;# Zobacz wcze&#347;niejsz&#261; i p&#243;&#378;niejsz&#261; warto&#347;&#263; za pomoc&#261;&lt;/span&gt;
&lt;span class="comment"&gt;# akcesora attr_name_change&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title_change&lt;/span&gt;  &lt;span class="comment"&gt;#=&amp;gt; [&amp;quot;Title&amp;quot;, &amp;quot;New Title&amp;quot;]&lt;/span&gt;

&lt;span class="comment"&gt;# Zapis atrybutu wykonuje zapytanie dotycz&#261;ce tylko jednej, &lt;/span&gt;
&lt;span class="comment"&gt;# odpowiadaj&#261;cej mu kolumny w tabeli:&lt;/span&gt;
&lt;span class="ident"&gt;article&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;save&lt;/span&gt;
  &lt;span class="comment"&gt;#=&amp;gt;  &amp;quot;UPDATE articles SET title = 'New Title' WHERE id = 1&amp;quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Dodano te&#380; co&#347;, co funkcjonalnie &amp;#8220;od zawsze&amp;#8221; by&#322;o obecne w &lt;a href="http://code.google.com/p/ruby-sequel/wiki/FilteringRecords"&gt;Sequel&amp;#8217;u&lt;/a&gt;, SQLAlchemy czy Django &lt;span class="caps"&gt;ORM&lt;/span&gt;, mianowicie tu nazywa si&#281; to &lt;a href="http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality"&gt;named scope&lt;/a&gt; (Rails wch&#322;on&#281;&#322;o popularny plugin &lt;a href="http://pivots.pivotallabs.com/users/nick/blog/articles/284-hasfinder-it-s-now-easier-than-ever-to-create-complex-re-usable-sql-queries"&gt;has_finder&lt;/a&gt; pozwalaj&#261;c w ko&#324;cu na &#322;atwiejsze budowanie bardziej skomplikowanych warunk&#243;w odpytywania bazy).&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;User&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;named_scope&lt;/span&gt; &lt;span class="symbol"&gt;:active&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:conditions&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:active&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="ident"&gt;named_scope&lt;/span&gt; &lt;span class="symbol"&gt;:inactive&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:conditions&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:active&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="ident"&gt;named_scope&lt;/span&gt; &lt;span class="symbol"&gt;:recent&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;lambda&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="symbol"&gt;:conditions&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;created_at &amp;gt; ?&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;week&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;ago&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="comment"&gt;# Typowe u&#380;ycie:&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;active&lt;/span&gt;    &lt;span class="comment"&gt;# to samo co User.find(:all, :conditions =&amp;gt; {:active =&amp;gt; true})&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;inactive&lt;/span&gt; &lt;span class="comment"&gt;# to samo co User.find(:all, :conditions =&amp;gt; {:active =&amp;gt; false})&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;recent&lt;/span&gt;   &lt;span class="comment"&gt;# to samo co User.find(:all, :conditions =&amp;gt; ['created_at &amp;gt; ?', 1.week.ago])&lt;/span&gt;

&lt;span class="comment"&gt;# Mo&#380;liwe s&#261; w ko&#324;cu kolejne zagnie&#380;d&#380;enia warunk&#243;w:&lt;/span&gt;
&lt;span class="constant"&gt;User&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;active&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;recent&lt;/span&gt;
  &lt;span class="comment"&gt;# to samo co:&lt;/span&gt;
  &lt;span class="comment"&gt;# User.with_scope(:conditions =&amp;gt; {:active =&amp;gt; true}) do&lt;/span&gt;
  &lt;span class="comment"&gt;#   User.find(:all, :conditions =&amp;gt; ['created_at &amp;gt; ?', 1.week.ago])&lt;/span&gt;
  &lt;span class="comment"&gt;# end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Autorzy Rails pozazdro&#347;cili &lt;a href="http://merbivore.org/documentation/merb-core/head/index.html?a=M000275&amp;#38;name=dependency"&gt;Merbowi&lt;/a&gt; i dodali te&#380; mo&#380;liwo&#347;&#263; &#322;adowania gem&#243;w o konkretnej wersji (by&#263; mo&#380;e b&#281;dzie to te&#380; pocz&#261;tek ko&#324;ca plugin&#243;w w obecnej postaci i Rails p&#243;jdzie i tu &#347;cie&#380;k&#261; Merba?)&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;Rails&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Initializer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;run&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;config&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; 

  &lt;span class="comment"&gt;# Za&#322;aduj najnowsz&#261; wersj&#281; haml&lt;/span&gt;
  &lt;span class="ident"&gt;config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;haml&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

  &lt;span class="comment"&gt;# Za&#322;aduj konkretn&#261; wersj&#281; chronic&lt;/span&gt;
  &lt;span class="ident"&gt;config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;chronic&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:version&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;0.2.3&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

  &lt;span class="comment"&gt;# Za&#322;aduj gem z repozytorium innego ni&#380; RubyForge&lt;/span&gt;
  &lt;span class="ident"&gt;config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;hpricot&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:source&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;http://code.whytheluckystiff.net&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

  &lt;span class="comment"&gt;# Za&#322;aduj gem kt&#243;rego nazwa pliku jest inna ni&#380; nazwa gemu&lt;/span&gt;
  &lt;span class="comment"&gt;# Np. mo&#380;na za&#322;adowa&#263; gem kt&#243;ry potrzebuje require 'aws/s3' zamiast &lt;/span&gt;
  &lt;span class="comment"&gt;# require 'aws-s3'&lt;/span&gt;
  &lt;span class="ident"&gt;config&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;gem&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aws-s3&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:lib&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;aws/s3&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; 
&lt;span class="keyword"&gt;end&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Cieszy te&#380;, &#380;e poprawiono &lt;a href="http://ryandaigle.com/articles/2007/12/19/what-s-new-in-edge-rails-pluggable-controller-caching"&gt;spos&#243;b dzia&#322;ania buforowania&lt;/a&gt; oraz wbudowano &lt;a href="http://ryandaigle.com/articles/2008/1/25/what-s-new-in-edge-rails-easier-timezones"&gt;lepsz&#261;&#160;obs&#322;ug&#281; dat i stref czasowych&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Ale z tego wszystkiego najbardziej mnie cieszy informacja inna informacja. Wspomina&#322;em o tym &lt;a href="http://blog.zabiello.com/articles/2008/03/30/rubyconf2008-merb"&gt;trzy dni temu&lt;/a&gt;, teraz zosta&#322;o to &lt;a href="http://weblog.rubyonrails.org/2008/4/2/rails-is-moving-from-svn-to-git"&gt;oficjalnie og&#322;oszone&lt;/a&gt;: &lt;strong&gt;Rails migruje z Subversion na Gita.&lt;/strong&gt;  W ko&#324;cu b&#281;dzie mo&#380;na liczy&#263; na powa&#380;niejsze przy&#347;pieszenie prac i szybsze nanoszenie zg&#322;aszanych poprawek (do tej pory to by&#322;o tragicznie wolne, np. zg&#322;oszony przeze mnie patch uwzgl&#281;dniono po 8 miesi&#261;cach). Rails, identycznie jak Merb, b&#281;dzie u&#380;ywa&#322; tego samego serwera &lt;a href="http://github.com/"&gt;GitHub&lt;/a&gt; dla kodu i &lt;a href="http://www.lighthouseapp.com/"&gt;LightHouse&lt;/a&gt;. Wi&#281;c ci, co nie maj&#261; tam kont, mog&#261; ju&#380; teraz o to zadba&#263;. Praca z Git r&#243;&#380;ni si&#281; te&#380; bardzo do &lt;span class="caps"&gt;SVN&lt;/span&gt;. Troch&#281; przydatnych link&#243;w:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://git.or.cz/"&gt;Git homepage&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://git.or.cz/course/svn.html"&gt;Git for &lt;span class="caps"&gt;SVN&lt;/span&gt;&#8217;ers crash course&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://jointheconversation.org/railsgit"&gt; 
Using Git to Manage and Deploy your Rails Apps&lt;/a&gt; (video)&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://utsl.gen.nz/talks/git-svn/intro.html"&gt;An introduction to git-svn for Subversion/SVK users and deserters&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://eagain.net/articles/git-for-computer-scientists/"&gt;Git for Computer Scientists&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://evil.che.lu/projects/braid"&gt;Braid, a Piston clone for Git&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://brian.maybeyoureinsane.net/blog/2008/01/31/git-sake-tasks" title="Rake tasks for performing git operations"&gt;Git Sake Tasks&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://kurt.karmalab.org/articles/2008/02/18/the-power-of-git-git-stash"&gt;The Power of Git: git stash&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://kurt.karmalab.org/articles/2008/02/19/the-power-of-git-part-2"&gt;The Power of Git, Part 2&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://peepcode.com/products/git"&gt;PeeCode: Git&lt;/a&gt; (video)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;W komentarzach do newsu na stronie Rails&#243;w mo&#380;na znale&#378;&#263; g&#322;osy rozczarowania tych, co u&#380;ywaj&#261; system Windows. Woleli by aby wybrano bardziej multiplatformowy Mercurial, ale &lt;span class="caps"&gt;DHH&lt;/span&gt; uci&#261;&#322; dyskusj&#281; m&#243;wi&#261;c, &#380;e decyzja zosta&#322;a ju&#380;&#160;podj&#281;ta a kolejne wersje Rails b&#281;d&#261; i tak dost&#281;pne standardowo w gemach. Poza tym na razie Git mo&#380;e by&#263; od biedy u&#380;ywany pod Cygwinem i jest te&#380; projekt &lt;a href="http://code.google.com/p/msysgit/"&gt;msysgit&lt;/a&gt;. No c&#243;&#380;, mnie to ma&#322;o interesuje. Ka&#380;dy wie, &#380;e windows i tak &lt;em&gt;sucks&lt;/em&gt; i najlepiej pracuje tylko ze samym sob&#261;. Rails ma za&#347; silniejsze zwi&#261;zki z &#347;wiatem &lt;span class="caps"&gt;POSIX&lt;/span&gt;, dlatego najlepiej u&#380;ywa&#263; Ubuntu, Mac &lt;span class="caps"&gt;OS X&lt;/span&gt; czy innych system&#243;w uniksowych. &lt;span class="caps"&gt;BTW&lt;/span&gt;, nowy Kubuntu 8.0.4 beta nawet nie&#378;le &#347;miga na VMWare pod Win32. :)&lt;/p&gt;</description>
      <pubDate>Thu, 03 Apr 2008 04:58:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:e24d08c2-c810-4335-92fd-77e5394c849c</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2008/04/03/rails21-coming</link>
      <category>rails</category>
      <category>ruby</category>
    </item>
  </channel>
</rss>
