<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <id>tag:myruby.net,:/pages</id>
  <link type="text/html" href="http://myruby.net" rel="alternate" />
  
  <title>myRuby.net</title>
  <updated>2009-05-14T01:51:24Z</updated>
  <logo>http://static.flickr.com/79/269367350_966f91013c_s.jpg</logo><link rel="self" href="http://feeds.feedburner.com/myruby" type="application/atom+xml" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><entry>
    <id>tag:myruby.net,:Page/3384917</id>
    <link type="text/html" href="http://feedproxy.google.com/~r/myruby/~3/tD8AE7s55DM/3384917" rel="alternate" />
    <title>레일스 2.3은 이전 버전보다 빨라졌을까?</title>
    <content type="html">&lt;p&gt;오랜만에 &lt;a href="/pages/320379" title="Rails Deployment" class="wiki"&gt;Rails Deployment&lt;/a&gt;란에 글을 쓴다.&amp;nbsp;이 분야도 꽤 안정되어버렸기에 요새는 크게 할 말이 없는게 이유이기도 하다.&lt;/p&gt;
&lt;p&gt;새로운 뉴스라면 &lt;a href="http://rubyseminar.springnote.com/pages/3163128" title="http://rubyseminar.springnote.com/pages/3163128" class="external"&gt;최근 Passenger Phusion이 nginx를 지원하게 된 것 정도&lt;/a&gt;일 것 같다,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;암튼, 제목 그대로 레일스 2.3은 이전 버전보다 더 나은 성능을 보여줄까?&lt;/p&gt;
&lt;p&gt;성질급한 분들을 위해 결론부터 이야기하자면,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(153, 0, 2); font-size: x-large;"&gt;네, 빨라졌더군요!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그럼 이제 증거를 제시할 차례일 것 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;증거&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.springnote.com/" title="http://www.springnote.com/" class="external"&gt;스프링노트 서비스&lt;/a&gt;를 레일스 2.2와 2.3에 각각 돌려보았다. 그리고 미리 정의한 3가지 액션에 대해 밴치마크를 진행하였다. 결과 그래프는 아래와 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="attachment" title="그림_12.png" src="http://deepblue.springnote.com/pages/3384917/attachments/1561161" height="374" alt="그림_12.png" width="471" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Y축은 평균 응답 시간(ms)이다. 당연히 아래 있을수록 좋은 값이다.&lt;/p&gt;
&lt;p&gt;그래프를 보면 Rails 2.3 with memcached patch라는 항목이 Rails 2.2보다 &lt;strong&gt;더 나은 성능을 보임을 확인할 수 있다&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그런데 맨 위에 가장 느리게 나온 Rails 2.3 Default는 뭔가?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그 이유는 &lt;a href="http://www.ruby-forum.com/topic/184119" title="http://www.ruby-forum.com/topic/184119" class="external"&gt;Memcached 1.6.5 (Rails 2.3) 10x slower - Ruby Forum&lt;/a&gt;에서 찾을 수 있다.&lt;/p&gt;
&lt;p&gt;간단히 요약하자면, 레일스 2.3에서 번들된 memcached 1.6.5에 추가된 타임아웃 기능이 성능차를 부른다는 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;(쉽게 예측할 수 있듯, 고질적인 루비 1.8의 스레드 성능 이슈 때문이다)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;해결 방법은 Timeout을 끄거나 Memached 최신 버전(1.7.2) + SystemTimer를 사용하는 것이다. 나는 간편하게 전자를 택했다.&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(153, 153, 153);"&gt;(후자도 테스트해보았는데, 비슷한 결과를 얻을 수 있었다)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;이 쯤에서 살포시 주의&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;사실 이 한가지 데이터 하나로 결론을 내리는 것은 어리석은 일이다.&lt;/p&gt;
&lt;p&gt;그리고 절대 남의 벤치마크 결과를 믿어서는 안될 일이다.&lt;/p&gt;
&lt;p&gt;확답을 위해서는 직접(!) 벤치마크를 해보시라 ^^&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;의문들&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;왜 빨라졌을까?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://rails23-book.springnote.com/" title="http://rails23-book.springnote.com/" class="external"&gt;2.3 릴리즈 노트&lt;/a&gt;를 보며 그 이유를 유추해볼 수 있을 것 같다. 개인적인 판단으로는 라우팅쪽 최적화, CGI.rb를 걷어낸 부분이 크지 않았을까 추측해본다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;더 빨라질까?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;다음 메이저 업데이트가 될 3.0 버전은 꽤 빨라질 것이라 기대하고 있다.&lt;/p&gt;
&lt;p&gt;그리고 루비 1.9나 JRuby가 대세가 되면 느리다는 인식은 사라질거라고 생각된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;약간 시간이 남았어요~&lt;/h3&gt;
&lt;p&gt;여기까지 하고 약간 시간이 남아서 오랜만에 Passenger와 (이벤트기반) 몽그렐의 성능을 측정해보았다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그 결과는 아래와 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="attachment" title="그림_13.png" src="http://deepblue.springnote.com/pages/3384917/attachments/1561163" height="302" alt="그림_13.png" width="357" /&gt; &lt;img class="attachment" title="그림_14.png" src="http://deepblue.springnote.com/pages/3384917/attachments/1561165" height="294" alt="그림_14.png" width="355" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;특이하게도 2.2 버전에서는 passenger가 더 나은 성능을 보여주는데,&lt;/p&gt;
&lt;p&gt;2.3에서는 거의 비슷하거나(passenger가 약간 빠른) 모습을 보인다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그 이유가 뭘까?&lt;/p&gt;
&lt;p&gt;아직 답을 찾아보지 않았지만, 꽤 재미있는 고민거리가 될 수 있을 것 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;참고&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/pages/320379" title="Rails Deployment" class="wiki"&gt;Rails Deployment&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/myruby?a=tD8AE7s55DM:7_C3q_VLjG8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/myruby?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/myruby/~4/tD8AE7s55DM" height="1" width="1"/&gt;</content>
    <author>
      <name>deepblue</name>
    </author>
  <feedburner:origLink>http://myruby.net/pages/3384917</feedburner:origLink></entry>
  <entry>
    <id>tag:myruby.net,:Page/3307963</id>
    <link type="text/html" href="http://feedproxy.google.com/~r/myruby/~3/6jVXytAuMZ4/3307963" rel="alternate" />
    <title>ClipNote - 긁어서 스프링노트로 뿅~</title>
    <content type="html">&lt;p&gt;클립노트는 클립보드의 텍스트를 스프링노트에 쉽게 기록할 수 있게 도와주는&amp;nbsp;매시업&amp;nbsp;애플리케이션입니다. 아래 URL에서 자세한 정보를 찾을 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img title="clipnote081.png" class="attachment" src="http://mashups.springnote.com/pages/1711340/attachments/1524713" alt="clipnote081.png" /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img title="" class="attachment emoticon" src="http://static.springnote.com/images/icon/emoticon18.gif" height="24" alt="" width="16" /&gt;&amp;nbsp;&lt;a href="http://mashups.springnote.com/pages/1711340"&gt;&lt;span style="COLOR: #810081;"&gt;http://mashups.springnote.com/pages/1711340&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;클립보드에 복사하고 ALT+F12를 누르면 미리 설정해둔 스프링노트 페이지에 저장되는 식입니다. 텍스트뿐 아니라 파일, 이미지등도&amp;nbsp;전송가능하므로 스프링노트에 중독되신 분들에게는 꽤 유용할 것&amp;nbsp;같군요.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;소스코드는 github에 있습니다. &lt;a href="/pages/3302993" title="Springnote# - Springnote for .NET" class="wiki"&gt;&lt;span style="COLOR: #810081;"&gt;Springnote# - Springnote for .NET&lt;/span&gt;&lt;/a&gt;도 필요하겠군요!&lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #999999;"&gt;(아직 .NET과 C#에 걸음마 수준이라 코드가 읽을만하지는 않은 듯 합니다)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img title="" class="attachment emoticon" src="http://static.springnote.com/images/icon/emoticon18.gif" height="24" alt="" width="16" /&gt;&amp;nbsp;&lt;a href="http://github.com/deepblue/clipnote/tree/master"&gt;&lt;span style="COLOR: #810081;"&gt;http://github.com/deepblue/clipnote/tree/master&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;잡담&lt;/h3&gt;
&lt;p&gt;오랜만에&amp;nbsp;다시 정적 타입 언어로 개발을 하니 재미있다. 특히나 좋은 IDE가 주는 장점을 (잊고 있다가) 다시 몸으로 느끼게 되는 것 같다.&amp;nbsp;경고없이 컴파일만 되면 모든&amp;nbsp;기능이 잘 돌아갈 것 같은 환상에 빠지는데 이건 루비할 때 테스트만 다 통과하면 땡인 것 같은&amp;nbsp;&amp;nbsp;것과 비슷하게 무서운 착각이다. 어느쪽이 더 나쁜(?) 일인지는 잘 모르겠지만 :)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;언어나 개발환경이 바뀌면 거기에 맞게 사고의 틀도 조금 바뀌어줘야 하는데 이게 생각보다 쉽지 않은 일이다.&amp;nbsp;의도적인 연습이 더 필요할 것 같다.&lt;/p&gt;
&lt;p&gt;아,&amp;nbsp;C++ 코드를 짜던 습관으로 루비 개발을 할 때 느꼈던 이질감을 C#하면서 다시 느끼게 될 줄을 몰랐다 :)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;.NET 덕분에 윈도우 애플리케이션 개발이&amp;nbsp;예전 Win32 시절에 비해&amp;nbsp;훨씬&amp;nbsp;환경이 좋아졌음을 느낀다.&amp;nbsp;운영체제 수준까지 모두 바뀌지 않은탓인지 아직 어색하게 Win32 API를 호출해야하는 부분등이 남아있기는 하지만 계속 좋아질 것 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/myruby?a=6jVXytAuMZ4:fKZRMBjgYNg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/myruby?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/myruby/~4/6jVXytAuMZ4" height="1" width="1"/&gt;</content>
    <author>
      <name>deepblue</name>
    </author>
  <feedburner:origLink>http://myruby.net/pages/3307963</feedburner:origLink></entry>
  <entry>
    <id>tag:myruby.net,:Page/3302993</id>
    <link type="text/html" href="http://feedproxy.google.com/~r/myruby/~3/u8iAu5Va0cM/3302993" rel="alternate" />
    <title>Springnote# - Springnote for .NET</title>
    <content type="html">&lt;p&gt;.NET 환경에서 &lt;a href="http://dev.springnote.com/" title="http://dev.springnote.com/" class="external"&gt;스프링노트 OpenAPI&lt;/a&gt;를 사용할 수 있도록 만든 컨슈머 라이브러리입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;전체 소스코드는 &lt;a href="http://github.com/deepblue/springnote_sharp/tree/master" title="http://github.com/deepblue/springnote_sharp/tree/master" class="external"&gt;github&lt;/a&gt;에 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;git clone&amp;nbsp;git://github.com/deepblue/springnote_sharp.git&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;주의&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;완벽하지 않습니다.&lt;/li&gt;
&lt;li&gt;API가 계속 바뀔 가능성이 매우 높습니다.&lt;/li&gt;
&lt;li&gt;개발자가 C#&amp;nbsp;초보이므로,&amp;nbsp;코드 품질이 떨어질 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;사용법(1) - 인증&lt;/h3&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: 돋움;"&gt;컨슈머 만들기&lt;/span&gt;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;using OAuth;&lt;br /&gt;
using Springnote;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;OAuthToken accessToken = new OAuthToken("ConsumerToken", "ConsumerTokenSecret");&lt;br /&gt;
Consumer consumer = new Consumer(GetConsumerToken(), accessToken);&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;사용법(2) - 페이지 객체 다루기&lt;/h3&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: 굴림체;"&gt;노트 객체 만들기&lt;/span&gt;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;&amp;nbsp;Note note = new Note("deepblue", consumer);&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: 굴림체;"&gt;페이지 불러오기&lt;/span&gt;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;&lt;span style="FONT-FAMILY: 굴림체;"&gt;&amp;nbsp;&lt;/span&gt;Page page = note.FindPage("2779230");&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: 굴림체;"&gt;페이지 제목 수정&lt;/span&gt;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;page.Title += "(modified)";&lt;/li&gt;
&lt;li&gt;page.Save();&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;사용법(3)&amp;nbsp;- 첨부 객체 다루기&lt;/h3&gt;
&lt;p&gt;파일을 첨부한다.&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;&amp;nbsp;Attachment at = page.CreateAttchment("c:\\test.png", true);&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Projects&lt;/h3&gt;
&lt;p&gt;아래 프로젝트에서 이 라이브러리를 사용합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/pages/3307963" title="ClipNote" class="wiki"&gt;ClipNote&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Thanks&lt;/h3&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: 돋움; COLOR: #223d67;"&gt;이 코드는 많은 부분을 &lt;a href="http://oauth.net/code" title="http://oauth.net/code" class="external"&gt;OAuthBase&lt;/a&gt;와&amp;nbsp;Kevin Davie씨의&amp;nbsp;&lt;a href="http://github.com/kdavie/yammer.net/tree/master" title="http://github.com/kdavie/yammer.net/tree/master" class="external"&gt;Yammer.net&lt;/a&gt; 코드에서 가져왔습니다.&amp;nbsp;원개발자분들께 감사드립니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/myruby?a=u8iAu5Va0cM:Yb6qv6NP94E:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/myruby?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/myruby/~4/u8iAu5Va0cM" height="1" width="1"/&gt;</content>
    <author>
      <name>deepblue</name>
    </author>
  <feedburner:origLink>http://myruby.net/pages/3302993</feedburner:origLink></entry>
  <entry>
    <id>tag:myruby.net,:Page/3152058</id>
    <link type="text/html" href="http://feedproxy.google.com/~r/myruby/~3/NIWVKuIbFCg/3152058" rel="alternate" />
    <title>쉽고 빠른 웹 개발 Django</title>
    <content type="html">&lt;p&gt;&lt;img title="L.jpg" class="attachment" src="http://deepblue.springnote.com/pages/3152058/attachments/1423688" alt="L.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;이미지 출처: &lt;a href="http://www.yes24.com/24/goods/3348853" class="external" title="http://www.yes24.com/24/goods/3348853"&gt;YES24&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;오랜만에 국내 서점가에 등장한 파이썬 책이라 더욱 반갑다. (&lt;span style="color: rgb(153, 153, 153);"&gt;GAE가 자바를 공식지원하면서 다소 의미가 퇴색되버리기는 했지만&lt;/span&gt;)&amp;nbsp;구글 웹 엔진용 예제 코드를 실은 역자의 노력도 감동적이었다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;나는 Django하면&amp;nbsp;RailsEnvy에서 제작한 재미있는 CF &lt;a href="http://railsenvy.com/2007/9/10/ruby-on-rails-vs-django-commercial-7" class="external" title="http://railsenvy.com/2007/9/10/ruby-on-rails-vs-django-commercial-7"&gt;Ruby on Rails vs. Django&lt;/a&gt;가 떠오른다. 항상 바보스런(?) 역할을 맡던 &lt;a href="/pages/search?q=jasonseifer&amp;amp;parent_id=3152058" class="wiki" title="jasonseifer"&gt;Jason Seifer&lt;/a&gt;가 Django편에서는 멋쟁이 DJ. 앵고로 등장했다. 하하. 레일스 커뮤니티에서는 레일스가 없었다면 Django를 사용했을거라는 충격적인(?) 고백이 유행하기도 했다 :) 변화와 유행에 민감한 루비스트들이 보기에도 Django는 훌륭한 프레임웍이 분명한 것 같다. 게다가 파이썬은 루비처럼 성능에 대한 끊이지 않은 논쟁도 없지 않은가! 이것만으로도 Django 사용을 고려하기에도 충분해 보인다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;오랜만에 파이썬 코드를 읽었더니, 기분이 상쾌해지는 기분도 들었다. 루비와 파이썬은 비슷한 것 같으면서 전혀 다른 언어다. 다른 언어, 다른 생각으로 만든 코드들을 꾸준히 읽어서 머리와 생각이 고착화되는건 어떻게든 막아야하니, 좋은 시도였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;책의 구성도 좋았다. 예제를 따라 가벼운 마음으로 Django 개발을 간접 체험할 수 있었다. 그치만 테스트에 대해 다룬 부분이 너무 적은것은 아쉬웠다.&amp;nbsp;의도적으로라도 T(B)DD를 해야겠다는 생각과 Django 진영은 어떻게 접근하는지 궁금했는데 말이다. 따로 자료 조사를 해봐야겠다. 아, 맞다. 긴 메서드와 if를 중첩해 사용한 예제 코드가 내 스타일은 아니어서 어느 순간 막 머릿속으로 리팩토링 하고 있기도 했다 -_-;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이제 직접 체험을 해봐야할텐데.... &lt;span style="color: rgb(153, 153, 153);"&gt;GAE가 자바도 지원해버리는 바람에 우선 순위가 살짝 밀려버렸다;;;;;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;가볍고 생산성을 중시하는 Django같은 실용적인 개발 환경이 득세하는 날이 오기를 기원하며 글을 마친다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;참고&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.djangoproject.com/" class="external" title="http://www.djangoproject.com/"&gt;Django!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.insightbook.co.kr/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%9D%BC%EB%A9%B4-%EC%9E%A5%EA%B3%A0#recentTrackback" class="external" title="http://blog.insightbook.co.kr/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%9D%BC%EB%A9%B4-%EC%9E%A5%EA%B3%A0#recentTrackback"&gt;파이썬 개발자라면 장고(Django)!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://insightbook.springnote.com/pages/2841126" class="external" title="http://insightbook.springnote.com/pages/2841126"&gt;스프링노트 페이지&lt;/a&gt; - 책소개, 목차, 정오표&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/myruby?a=NIWVKuIbFCg:JG7mW32YQNc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/myruby?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/myruby/~4/NIWVKuIbFCg" height="1" width="1"/&gt;</content>
    <author>
      <name>deepblue</name>
    </author>
  <feedburner:origLink>http://myruby.net/pages/3152058</feedburner:origLink></entry>
  <entry>
    <id>tag:myruby.net,:Page/3008340</id>
    <link type="text/html" href="http://feedproxy.google.com/~r/myruby/~3/8w8i77fUdHw/3008340" rel="alternate" />
    <title>BDD with rspec &amp; cucumber</title>
    <content type="html">&lt;p&gt;스프링노트팀 개발자들에서 공유한 내용이다.&lt;/p&gt;
&lt;p&gt;급조한 자료이고, 이것만으로는 큰 도움이 되지 않겠지만, 혹시나 하는 마음에 올려본다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.pragprog.com/titles/achbd/the-rspec-book" class="external" title="http://www.pragprog.com/titles/achbd/the-rspec-book"&gt;The RSpec Book&lt;/a&gt;(베타북)을 기다려 읽는 재미가 쏠쏠하다. 이대로라면 꽤 괜찮은 책이 될 것 같다.&lt;/p&gt;
&lt;p&gt;책에서 이야기하는 BDD Cycle이 인상적이라 그 느낌을 전달하고자했는데, 어땠을려나..&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;object height="420" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0" width="500"&gt;&lt;param name="movie" value="http://filefarm.storyq.net/SlideView.swf?boxKey=001238340309009350" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;embed src="http://filefarm.storyq.net/SlideView.swf?boxKey=001238340309009350" type="application/x-shockwave-flash" height="420" width="500" /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;발표자료 내려받기: &lt;a href="http://deepblue.springnote.com/pages/3008340/attachments/1348672" class="attachment" title="bdd_with_rspec_and_cucumber.pdf"&gt;bdd_with_rspec_and_cucumber.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;참고자료&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://delicious.com/byblue/bdd"&gt;&lt;/a&gt;&lt;a href="http://delicious.com/byblue/bdd"&gt;http://delicious.com/byblue/bdd&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/myruby?a=8w8i77fUdHw:eunmC5XFxzs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/myruby?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/myruby/~4/8w8i77fUdHw" height="1" width="1"/&gt;</content>
    <author>
      <name>deepblue</name>
    </author>
  <feedburner:origLink>http://myruby.net/pages/3008340</feedburner:origLink></entry>
  <entry>
    <id>tag:myruby.net,:Page/2900134</id>
    <link type="text/html" href="http://feedproxy.google.com/~r/myruby/~3/l0M_1vKFjS8/2900134" rel="alternate" />
    <title>앗! 뜨거~ 딜리셔스와 트위터로 루비 소식 나누기</title>
    <content type="html">&lt;p&gt;정말 오랜만에&lt;span style="color: rgb(102, 102, 102);"&gt;(사실 오픈 후 처음으로^^)&lt;/span&gt; &lt;a href="/pages/1330384" title="뜨거운 루비 - 함께 전하는 루비 뉴스" class="wiki"&gt;뜨거운 루비 - 함께 전하는 루비 뉴스&lt;/a&gt;의 &lt;span style="color: rgb(182, 80, 6);"&gt;업데이트&lt;/span&gt; 소식을 알려드립니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;대표적인 소셜 미디어라고 할 수 있는 &lt;a href="http://delicious.com/" title="http://delicious.com/" class="external"&gt;딜리셔스&lt;/a&gt;와 &lt;a href="http://twitter.com/" title="http://twitter.com/" class="external"&gt;트위터&lt;/a&gt;로 뜨거운 루비에 포스팅을 할 수 있게 되었습니다. 이제 글이 더 많이 올라오겠죠? :) &lt;span style="color: rgb(102, 102, 102);"&gt;(오랜만의 블로그 포스팅인데 한줄만 쓰고 마칠 수 없으니.... 스샷이 이어집니다)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;안녕, delicious!&lt;/h3&gt;
&lt;p&gt;북마크 도구로 딜리셔스를 사용하고 계신가요?&lt;/p&gt;
&lt;p&gt;그렇다면 재미있는 루비관련 글을 만날때마다 &lt;strong&gt;for:hotruby 태그&lt;/strong&gt;를 추가해보세요~&lt;/p&gt;
&lt;p&gt;&lt;img title="그림_6.png" class="attachment" src="http://deepblue.springnote.com/pages/2900134/attachments/1294400" height="209" alt="그림_6.png" width="510" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;잠시 후 뜨거운 루비 사이트를 통해 약간 더 많은 이들에게 유용한 정보를 선사할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img class="attachment" title="그림_11.png" src="http://deepblue.springnote.com/pages/2900134/attachments/1294496" height="177" alt="그림_11.png" width="496" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://hot.rubykr.org/items/2900054/12371679664509" class="external" title="http://hot.rubykr.org/items/2900054/12371679664509"&gt;포스팅된 예는 여기&lt;/a&gt; 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;안녕, 트위터!&lt;/h3&gt;
&lt;p&gt;혹시 트위터 사용자세요?&lt;/p&gt;
&lt;p&gt;그럼 &lt;a href="http://twitter.com/hotruby" title="http://twitter.com/hotruby" class="external"&gt;@hotruby&lt;/a&gt;를 follow 하시고, Reply를 보내주세요. &lt;strong&gt;@hotruby&lt;/strong&gt;로 시작하면 되는거 아시죠?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img title="그림_8.png" class="attachment" src="http://deepblue.springnote.com/pages/2900134/attachments/1294406" height="279" alt="그림_8.png" width="498" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;잠시 후, 더 뜨거워진 소식을 만날 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;.&lt;img title="그림_9.png" class="attachment" src="http://deepblue.springnote.com/pages/2900134/attachments/1294408" height="161" alt="그림_9.png" width="497" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://hot.rubykr.org/items/2900054/12371679639589" class="external" title="http://hot.rubykr.org/items/2900054/12371679639589"&gt;포스팅된 예는 여기&lt;/a&gt; 있습니다. 차암~~ 쉽죠오잉~&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;멀리 멀리 퍼져라~&lt;/h3&gt;
&lt;p&gt;요즘의 웹은 참 재미있는 것 같습니다. 한곳에 모였다가, 또 펴졌다가.... 모였다가 퍼졌다가..&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;자주 사용하는 서비스에서 뜨거운 루비에 포스팅하고 싶으신 분들 있으시죠?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://github.com/deepblue/hotruby/tree/master" title="http://github.com/deepblue/hotruby/tree/master" class="external"&gt;hotruby 프로젝트&lt;/a&gt; fork 하셔서 수정하시고 연락(pull request)주세요 ^^ 언제든 환영합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/myruby?a=l0M_1vKFjS8:CKJ2qjDug5g:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/myruby?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/myruby/~4/l0M_1vKFjS8" height="1" width="1"/&gt;</content>
    <author>
      <name>deepblue</name>
    </author>
  <feedburner:origLink>http://myruby.net/pages/2900134</feedburner:origLink></entry>
  <entry>
    <id>tag:myruby.net,:Page/2359020</id>
    <link type="text/html" href="http://feedproxy.google.com/~r/myruby/~3/SsT6OJx-JXA/2359020" rel="alternate" />
    <title>2008년을 보내며</title>
    <content type="html">&lt;p&gt;작년 이맘때, '성공한 느낌'을&amp;nbsp;가지며 2008년을 마무리할 수 있기를 바란다는 작은(?) 소망을 이야기한 적 있다.&lt;/p&gt;
&lt;p&gt;그리고 1년이 정말 번개처럼 지나가버렸다. 1년동안 나는 무엇을 얻고 무엇을 잃은 것일까?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://springnote.com/"&gt;&lt;img class="attachment" title="스프링노트와_함께하는_크리스마스~.jpg" src="http://deepblue.springnote.com/pages/2359020/attachments/1041246" alt="스프링노트와_함께하는_크리스마스~.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;자기 반성&lt;span style="color: rgb(121, 121, 121);"&gt;(+비판)&lt;/span&gt; 차원에서 글을 쓰기 시작했지만, 크리스마스 카드를 계속 보고 있으니 마음이 따뜻해진다.&lt;/p&gt;
&lt;p&gt;2009년에는 항상 긍정적인 아우라로 주변을 변화시킬 수 있는 내가 되기를...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(254, 52, 152);"&gt;&lt;strong&gt;&lt;img title="" class="attachment emoticon" src="/images/icon/emoticon_xmas2.gif" alt="" /&gt; Happy Christmas!&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/myruby?a=ccXm2iaN"&gt;&lt;img src="http://feeds.feedburner.com/~f/myruby?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/myruby/~4/SsT6OJx-JXA" height="1" width="1"/&gt;</content>
    <author>
      <name>deepblue</name>
    </author>
  <feedburner:origLink>http://myruby.net/pages/2359020</feedburner:origLink></entry>
  <entry>
    <id>tag:myruby.net,:Page/2156590</id>
    <link type="text/html" href="http://feedproxy.google.com/~r/myruby/~3/GWvRo261V70/2156590" rel="alternate" />
    <title>레일스에서 특정 작업 비동기로 처리하기- Delayed Job 플러그인</title>
    <content type="html">&lt;p&gt;&lt;a href="http://ko.wikipedia.org/wiki/Getting_Things_Done" class="external" title="http://ko.wikipedia.org/wiki/Getting_Things_Done"&gt;GTD(Getting Things Done)&lt;/a&gt; 플로우를 보면 이런 부분이 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img title="그림_13.png" class="attachment" src="http://deepblue.springnote.com/pages/2156590/attachments/1008296" alt="그림_13.png" /&gt;&lt;/p&gt;
&lt;p&gt;그림 출처: &lt;a href="http://anabubula.com/content/3-more-GTD-wallpapers" class="external" title="http://anabubula.com/content/3-more-GTD-wallpapers"&gt;3 more GTD wallpapers!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;일을 할 때는 다음 작업을 찾아서, 2분안에 할 수 있으면 당장 해버리고 그렇지 않으면 미루거나 위임하라는 것이다. 이런 원칙은 빠른 응답이 생명인 요즘 웹 개발에도 똑같이 적용된다. 오래 걸릴만한 일은 미루고 일단 사용자에게 응답을 보내라는 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;약간 억지스러웠지만, 어쨌든 웹 애플리케이션을 개발할 때 비동기 작업이 필요한 경우는 꽤 많다. 예를 들어 스프링노트처럼 내 데이터 전체를 내려받게 해주는 기능이 있고 해보자. 이 기능은 오래 걸리기도 하지만, DB 쿼리도 많고, 압축이라도 한다면 CPU, Disk를 많이 소모하는 무거운 기능이다. 이런 기능은 비동기로 처리하는게 좋다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;비동기로 작업이 떠오르는 경우는 이럴때다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;'짧은 시간'안에 끝날 것이라는 보장할 수 없는 작업&lt;/li&gt;
&lt;li&gt;너무 많은 시스템 리소스를 소비하는 무거운 작업&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;특히나 레일스 애플리케이션은 비동기 작업이 더 절실한데.. 그 이유는 &lt;a href="/pages/320445" class="wiki" title="몽그렐 클러스터가 필요한 이유"&gt;몽그렐 클러스터가 필요한 이유&lt;/a&gt;에서 찾아보기 바란다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;당신의 선택은?&lt;/h3&gt;
&lt;p&gt;비동기 처리를 위해 사용할 수 있는 솔루션은 너무나도 많고 다양하다. 많이 언급되는 것들 중 몇가지를 선택해서 테스트한 후 고르는 것이 좋겠다. 아니면 일반화해서 나중에 플러그인만 바꿔 끼울 수 있도록 하는 것도 좋은 접근이다!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img title="그림_14.png" class="attachment" src="http://deepblue.springnote.com/pages/2156590/attachments/1008456" alt="그림_14.png" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;그림&amp;gt; 선택이 너무 많다. 출처는 &lt;a href="http://www.scribd.com/doc/2589535/Handling-LongRunning-Tasks-in-Rails" class="external" title="http://www.scribd.com/doc/2589535/Handling-LongRunning-Tasks-in-Rails"&gt;Handling Long-Running Tasks in Rails&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;내가 솔루션을 선택하는 방법은 일단 내가 가진 요구사항을 충족하는 '가장 가벼운' 것을 고르는 것이다. 혹시 나중에 필요할지 모르는 기능은 머릿속에서 지운다. 그리고 나중에 진짜 그 기능이 필요해지면, 그 때 고민해도 좋다. 그런 근거로 내가 선택한 것은 Shopify의 일부로 개발되었다는 &lt;a href="http://github.com/tobi/delayed_job/tree/master" class="external" title="http://github.com/tobi/delayed_job/tree/master"&gt;Delayed Job(DJ)&lt;/a&gt;이다. github팀의 &lt;a href="http://github.com/blog/197-the-new-queue" class="external" title="http://github.com/blog/197-the-new-queue"&gt;이 글&lt;/a&gt;에도 큰 영향을 받았다. 이 팀에서 DJ를 선택한 이유를 아래처럼 설명하고 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is simple, required no research beyond the short &lt;span class="caps"&gt;README&lt;/span&gt;, works wonderfully with Rails, is fast, is hackable, solves both the queue and the worker problems, and has no external dependecies. Also, it’s hosted on GitHub!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Delayed Job 설정 및 사용법&lt;/h3&gt;
&lt;p&gt;DJ는 DB를 Job Queue로 사용하므로, 아래처럼 마이그레이션을 수행해줘야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;create_table :delayed_jobs, :force =&amp;gt; true do |table|&lt;br /&gt;
&amp;nbsp; table.integer :priority, :default =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; table.integer :attempts, :default =&amp;gt; 0&lt;br /&gt;
&amp;nbsp; table.text :handler&lt;br /&gt;
&amp;nbsp; table.string :last_error&lt;br /&gt;
&amp;nbsp; table.datetime :run_at&lt;br /&gt;
&amp;nbsp; table.datetime :locked_at&lt;br /&gt;
&amp;nbsp; table.datetime :failed_at&lt;br /&gt;
&amp;nbsp; table.string :locked_by&lt;br /&gt;
&amp;nbsp; table.timestamps&lt;br /&gt;
end&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그리고 Job 객체를 만들어 위 테이블에 직렬화해서 넣어준다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;class NewsletterJob &amp;lt; Struct.new(:text, :emails)&lt;br /&gt;
&amp;nbsp; def perform&lt;br /&gt;
&amp;nbsp; &amp;nbsp;emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }&lt;br /&gt;
&amp;nbsp; end&lt;br /&gt;
end&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;큐에 작업을 넣는 코드는 아래와 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;Delayed::Job.enqueue NewsletterJob.new('lorem ipsum...', Customers.find(:all).collect(&amp;amp;:email))&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이게 DJ 사용법의 거의 전부다. 별도의 S/W를 설치할 필요가 없고, 사용법이 간결한 것이 가장 큰 장점이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Job Runner&lt;/h3&gt;
&lt;p&gt;이제, Job Queue에 담긴 내용을 꺼내서 실행하는 job_runner를 만들어준다. 아래와 같은 내용으로 script/job_runner를 작성한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;#!/usr/bin/env ruby&lt;br /&gt;
&lt;br /&gt;
unless ARGV.size == 2&lt;br /&gt;
&amp;nbsp; $stderr.puts "USAGE: #{$0} environment pid_file_path"&lt;br /&gt;
&amp;nbsp; exit 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
RAILS_ENV = ARGV[0]&lt;br /&gt;
File.open(ARGV[1], 'w+') {|f| f.write("#{$$}") }&lt;br /&gt;
&lt;br /&gt;
require File.dirname(__FILE__) + '/../config/environment'&lt;br /&gt;
Delayed::Worker.new.start&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;monit을 이용한 모니터링과 배포&lt;/h3&gt;
&lt;p&gt;&lt;img title="44570084_5be779d27d_m.jpg" class="attachment" src="http://deepblue.springnote.com/pages/2156590/attachments/1008660" alt="44570084_5be779d27d_m.jpg" style="margin: 0pt 0pt 0pt 1em; float: right;" /&gt;이 작업을 하기전에 가장 궁금했던 것이, 어떻게 job_runner를 관리하는가 였다. 여기서 관리라 함은,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;배포 후 최신 버전을 띄운다&lt;/li&gt;
&lt;li&gt;job_runner가 잘 돌아가고 있는지 모니터링 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;먼저 job_runner를 구동하는 컨트롤 프로그램을 작성한다. /bin/job_runner_ctl이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;#!/bin/bash&lt;br /&gt;
cd /path/to/app&lt;br /&gt;
&lt;br /&gt;
if [ "$1" == "start" ]; then&lt;br /&gt;
&amp;nbsp; nohup /usr/bin/ruby script/job_runner production /path/to/log/job_runner.pid &amp;amp;&lt;br /&gt;
else&lt;br /&gt;
&amp;nbsp; ps ux | awk '/script\/job_runner/ &amp;amp;&amp;amp; !/awk/ {print $2}' |xargs -i kill {}&lt;br /&gt;
&amp;nbsp; rm /path/to/log/job_runner.pid&lt;br /&gt;
fi&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그리고 job_runner_ctl을 &lt;a href="/pages/400053" class="wiki" title="monit을 이용한 몽그렐 프로세스 모니터링"&gt;monit&lt;/a&gt;에 등록한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;check process job_runner with pidfile /path/to/log/job_runner.pid&lt;br /&gt;
&amp;nbsp; start program = "/bin/job_runner_ctl start"&lt;br /&gt;
&amp;nbsp; stop program = "/bin/job_runner_ctl stop"&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
&amp;nbsp; if totalmem is greater than 1024.0 MB for 5 cycles then restart # eating up memory?&lt;br /&gt;
&amp;nbsp; if cpu is greater than 50% for 2 cycles then alert # s an email to admin&lt;br /&gt;
&amp;nbsp; if cpu is greater than 80% for 3 cycles then restart # hung process?&lt;br /&gt;
&amp;nbsp; if loadavg(5min) greater than 10 for 8 cycles then restart # bad, bad, bad&lt;br /&gt;
&amp;nbsp; if 3 restarts within 5 cycles then timeout # something is wrong, call the sys-admin&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;마지막으로 할 일은 Capistrano의 restart 작업에 job_runner를 재시작하는 명령을 추가하는 일이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;desc "restart web application servers"&lt;br /&gt;
task :restart, :roles =&amp;gt; :app do&lt;br /&gt;
&amp;nbsp; # (..omitted..)&lt;br /&gt;
&amp;nbsp; run "monit restart job_runner"&lt;br /&gt;
end&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;마치며&lt;/h3&gt;
&lt;p&gt;꽤 걱정을 했는데, 그에 비해 별 문제없이 Delayed Job을 서비스에 적용할 수 있었다. 조금 더 대용량을 다루는 사이트가 되면 그때는 Beanstalkd, starling, ActiveMQ 등을 고려해야할까? 일단은 defer it!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/myruby?a=KtPk2o2x"&gt;&lt;img src="http://feeds.feedburner.com/~f/myruby?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/myruby/~4/GWvRo261V70" height="1" width="1"/&gt;</content>
    <author>
      <name>deepblue</name>
    </author>
  <feedburner:origLink>http://myruby.net/pages/2156590</feedburner:origLink></entry>
  <entry>
    <id>tag:myruby.net,:Page/2043210</id>
    <link type="text/html" href="http://feedproxy.google.com/~r/myruby/~3/HkAqYZJ2-4o/2043210" rel="alternate" />
    <title>몽그렐 사용자를 위한 몇가지 팁</title>
    <content type="html">&lt;p&gt;지난 글 &lt;a href="/pages/1356708" class="wiki" title="변하지 않는 것은 없다. 이제 대세는 Passenger(aka. mod_rails)"&gt;변하지 않는 것은 없다. 이제 대세는 Passenger(aka. mod_rails)&lt;/a&gt;에서 말한대로 Passenger가 현재 시점에서 가장 추천할만한 환경임에 변함이 없다. 게다가 최근&amp;nbsp;&lt;a href="http://blog.phusion.nl/2008/10/29/phusion-passenger-now-with-global-queuing/" title="Phusion Passenger에 Global Queuing 기능이 들어갔다"&gt;Global Queuing 기능이 들어갔다&lt;/a&gt;는 소식은 기존 애플리케이션도 Passenger로 옮겨타는 것을 고려하도록 유혹한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;하지만, 이런 저런 이유로 아직도(?) 몽그렐을 사용하고 있는 곳을 위해 몇가지 팁을 공유한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;이벤트 머신을 활용한 Swiftiply&lt;/h3&gt;
&lt;p&gt;루비 1.8(MRI)의 경우,&amp;nbsp;설계상의 이유(그린 쓰레드) 때문에 &lt;a href="/pages/344683" title="이벤트 기반 몽그렐의 성능" class="wiki"&gt;이벤트 기반 몽그렐의 성능&lt;/a&gt;이 더 낫다. 단순히 swiftiply 젬을 설치하고 환경변수만 설정하면 되는 문제이므로, 이벤트 기반 몽그렐을 사용하는게 더 낫다. 안정성 문제는 전혀 없는 것으로 알려져있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;HAProxy를 이용한 글로벌 큐잉(Global Queuing)&lt;/h3&gt;
&lt;p&gt;보통 사용하는 HTTP 서버에서 제공하는 로더 밸런서(예를들어, 아파치라면 mod_proxy_balancer)를 사용하지만, HAProxy를 이용한 글로벌 큐잉을 도입히는게 낫다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; server myapp_3000 127.0.0.1:3000 check inter 60000 minconn 1 &lt;strong&gt;maxconn 1&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위처럼 HAProxy의 설정에서 maxconn을 1로 제한하면, HAProxy가 요청을 큐잉하면, 몽그렐에는 한번에 하나의 요청만을 보낸다. 약간 더 자세한 설명은 &lt;a href="/pages/774976" title="스프링노트 배포 환경 Before &amp;amp;amp; After: Capistrano, God, HAProxy, Seesaw!" class="wiki"&gt;스프링노트 배포 환경 Before &amp;amp; After: Capistrano, God, HAProxy, Seesaw!&lt;/a&gt;을 참고하면 좋겠다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;현 상태를 신고받는 mongrel_proctitle&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://github.com/rtomayko/mongrel_proctitle/tree/master" title="http://github.com/rtomayko/mongrel_proctitle/tree/master" class="external"&gt;mongrel_proctitle&lt;/a&gt; 젬을 설치하면 현재 처리하고 있는 요청에 대한 정보를 프로세스 타이틀로 표시해준다. 이런 식이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;mongrel_rails [10010/2/358]: handling 127.0.0.1: HEAD /feed/cal/global/91/6de4&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;여기 담긴 정보는 왼쪽부터 보자면 다음과 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The port that Mongrel is serving&lt;/li&gt;
&lt;li&gt;Requests currently queued/being processed concurrently&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Requests processed during server lifetime&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;What it's doing&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;The client IP&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;The current req (method / path)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;간단한 아이디어에서 시작했지만, 문제를 찾는데 걸리는 시간을 꽤 단축해주는 유용한 녀석이기도 하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참고로, Evented Mongrel의 경우는 mongrel_proctitle이 동작하지 않는다. mongrel_proctitle.rb 파일을 열어 아래 코드를 추가해주자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def dispatch_to_handlers_with_proctitle(handlers,request,response)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; unless @handler&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @handler = ProctitleHandler.new(@titler)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; register("/", @handler, true)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @titler.request do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return dispatch_to_handlers_without_proctitle(handlers,request,response)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; end&amp;nbsp;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; alias_method :dispatch_to_handlers_without_proctitle, :dispatch_to_handlers&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; alias_method :dispatch_to_handlers, :dispatch_to_handlers_with_proctitle&lt;br /&gt;
&amp;nbsp; end&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;참고&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/pages/320379" class="wiki" title="Rails Deployment"&gt;Rails Deployment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://del.icio.us/byblue/mongrel"&gt;http://del.icio.us/byblue/mongrel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/myruby?a=uaa2597c"&gt;&lt;img src="http://feeds.feedburner.com/~f/myruby?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/myruby/~4/HkAqYZJ2-4o" height="1" width="1"/&gt;</content>
    <author>
      <name>deepblue</name>
    </author>
  <feedburner:origLink>http://myruby.net/pages/2043210</feedburner:origLink></entry>
  <entry>
    <id>tag:myruby.net,:Page/2014332</id>
    <link type="text/html" href="http://feedproxy.google.com/~r/myruby/~3/ZgVxhdranrY/2014332" rel="alternate" />
    <title>파이썬으로 OAuth 컨슈머 만들기</title>
    <content type="html">&lt;p&gt;&lt;a href="http://leahculver.com/" class="external" title="http://leahculver.com/"&gt;Leah Culver&lt;/a&gt;씨가 공개한&amp;nbsp;&lt;a href="http://oauth.googlecode.com/svn/code/python/oauth/" class="external" title="http://oauth.googlecode.com/svn/code/python/oauth/"&gt;파이썬 라이브러리&lt;/a&gt;를 이용하면 어렵지 않게 OAuth 컨슈머를 구현할 수 있다. &lt;span style="color: rgb(121, 121, 121);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="color: rgb(121, 121, 121);"&gt;(하지만 라이브러리라기보다는 예제 코드에 가까워&amp;nbsp;사용하기 조금 불편한 API라는 느낌이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 코드에서 제공하는 예제를 살짝 수정해 스프링노트에 접속해서 페이지 하나를 가져오는 &lt;a href="http://github.com/deepblue/snippets/tree/master/springnote/python" class="external" title="http://github.com/deepblue/snippets/tree/master/springnote/python"&gt;OAuth 컨슈머 예제 코드&lt;/a&gt;를 만들었으니 필요하다면 참고하시길.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol class="code"&gt;
&lt;li&gt;# setup&lt;br /&gt;
client = SpringnoteClient(CONSUMER_TOKEN, CONSUMER_SECRET)&lt;br /&gt;
&lt;br /&gt;
# get request token&lt;br /&gt;
token = client.fetch_request_token()&lt;br /&gt;
print 'please visit %s in your browser and press any key.' % client.authorize_url(token)&lt;br /&gt;
&lt;br /&gt;
# get access token&lt;br /&gt;
token = client.fetch_access_token(token)&lt;br /&gt;
&lt;br /&gt;
# access some protected resources&lt;br /&gt;
print client.get_page(144, 'deepblue')&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;전체 소스 코드는 &lt;a href="http://github.com/deepblue/snippets/tree/master/springnote/python" class="external" title="http://github.com/deepblue/snippets/tree/master/springnote/python"&gt;여기&lt;/a&gt; 있다.&lt;/p&gt;
&lt;p&gt;조만간 파이썬용 스프링노트 클라이언트 라이브러리를 만들어 제공할 예정이다(&lt;a href="http://blog.openmaru.com/268" class="external" title="http://blog.openmaru.com/268"&gt;이 글&lt;/a&gt;의 주인공에게 제작 의뢰했음 ^^).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/myruby?a=Imr8JvVs"&gt;&lt;img src="http://feeds.feedburner.com/~f/myruby?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/myruby/~4/ZgVxhdranrY" height="1" width="1"/&gt;</content>
    <author>
      <name>deepblue</name>
    </author>
  <feedburner:origLink>http://myruby.net/pages/2014332</feedburner:origLink></entry>
</feed>
