#412 Fast Rails Commands
- Download:
- source codeProject Files in Zip (44.5 KB)
- mp4Full Size H.264 Video (21.7 MB)
- m4vSmaller H.264 Video (9.71 MB)
- webmFull Size VP8 Video (10 MB)
- ogvFull Size Theora Video (22.4 MB)
레일스 명령들이 실행시 다소 느려질 수 있다는 것을 아마도 알고 있을 것입니다. 예를 들어, 레일스 어플리케이션에 대해서 제너레이터를 실행할 때 결과를 볼 때가지 몇초정도 지연이 있습니다. 이것은, 이러한 명령들이 실행될 때 어플리케이션이 시작되기 때문인데, 이따금씩 어플리케이션이 개발모드에 서 실행되기 때문에 특히 테스트를 실행할 때 이러한 현상이 가장 눈에 띄게 보이게 됩니다. 어플리케이션이 커질수록 이러한 대기 시간이 길어지게 됩니다. 이번 연제에서는, 이러한 명령들이 훨씬 빠르게 실행될 수 있도록 만들어 주는 몇가지 툴을 소개하고자 합니다.
Zeus
제일 먼저 Zeus 라는 툴은 레일스 어플리케이션을 사전에 로드해서 명령을 바로 실행할 수 있도록 해 줍니다. 그러나 꽤나 엄격한 요구사항을 가지고 있어서 최신 버전의 OS X 이나 리눅스가 있어야 하고 gargage collection 패치된 루비 1.9.3 버전이 설치되어 있어야 사용할 수 있습니다. 패치하지 않아도 작동하는 것으로 보이나 RAM 크기가 제한적이면 패치가 필요할 수 있습니다. gem install zeus
명령을 실행하면 설치됩니다. 어플리케이션의 gemfile에 zeus를 추가해서는 안되는데, Bundler 외부에서 zeus
명령을 실행하도록 디자인되었기 때문입니다. 일단 설치가 되면, zeus start
명령을 실행하여 어플리케이션을 미리 로드할 수 있습니다.
레일스 어플리케이션이 로드되면 이 결과는 변경될 것입니다. 현재 어플리케이션에 대해서 초록색으로 변경된 것은 이 어플리케이션에 대해서 이러한 명령들을 사용할 수 있다는 것을 의미합니다. 또다른 터미널 탭을 열어, 일반적으로 사용하는 레일스 제너레이터 명령 대신에 zeus generate
(또는 줄여서 zeus g
) 명령을 실행하여 또 다른 제너레이터를 실행할 수 있습니다.
$ zeus g model comment content
이와 같이, rake db:migrate
명령을 실행할 때는 앞에 zeus
를 붙여 사용할 필요가 있습니다. 다른 Rake 명령에 대해서도 마찬가지입니다.
$ zeus rake db:migrate
또한 더 신속하게 실행되고 zeus rake test
명령으로 테스트를 실행할 경우에도 이전보다 훨씬 빠르게 실행됩니다. zeus test
명령을 이용해서 특정 테스트 파일이나 디렉토리를 실행할 수 있기 때문에 기능 테스트만을 실행하기 위해서는 zeus test test/functional
명령을 사용하면 될 것입니다.
이러한 명령을 실행할 때마다 레일스 어플리케이션을 시작할 필요가 없기 때문에, 결과는 훨씬 빠르게 나타날 것입니다. zeus는 다른 환경, 즉, 개발과 테스트 환경에서도 레일스를 미리 로딩하여 작동하기 때문에 어플리케이션에 Cucumber를 셋업한 경우에도 제대로 작동할 것입니다. 이것은 미리 로드된 환경에 대해서도 명령을 실행할 수 있다는 것을 의미합니다. zeus는 또한 변경된 내용도 멋지게 디시 로딩해 줍니다. 예를 들어 임의의 모델을 변경할 때에도 자동으로 변경된 부분을 잡아내기 때문에 zeus를 다시 로드할 필요가 없을 것입니다. zeus를 사용할 경우와 사용하지 않을 경우 명령실행에 소요되는 시간을 비교해 봅시다. 데이터베이스 마이그레이션을 실행해 보겠습니다.
$ time bundle exec rake db:migrate real 0m4.054s user 0m3.409s sys 0m0.569s $ time zeus rake db:migrate real 0m1.246s user 0m0.553s sys 0m0.162s
zeus를 사용하지 않을 경우에는 4초가 소요되었지만 사용할 경우에는 1초 미만내에 완료되었습니다. 이러한 차이는 어플리케이션의 크기에 많이 좌우되기 때문에 소요시간의 차이를 알아보기 위해 현 재어플리케이션을 가지고 테스트해 보는 것이 좋을 것입니다.
이와 같은 셋업으로 좋은 점은, 정말로 빠른 피드백을 위해서, 레일스 명령을 텍스트 에디터로 보다 훌륭하게 통할합 수 있도록 해줍니다. 예를 들어, Textmate를 사용하고 있다면, 셋업이 되어 있는 경우, 커서를 테스트 코드내에 둔 채, 단축키를 사용하면 해당 테스트를 실행해서 그 결과를 툴팁으로 보여 주게 됩니다. 이것은 커스텀 Textmate 번들을 만들어 현재 프로젝트 디렉토리로 옮긴 후에 블록으로 선택한 라인에서 현재의 파일에 대해서 zeus test
명령을 실행하므로서 작동하게 됩니다.
cd "$TM_PROJECT_DIRECTORY" zeus test "$TM_FILEPATH:$TM_LINE_NUMBER"
zeus를 실행할 때 알아두어야 할 것은 프로젝트 루트에 .zeus.sock
파일을 생성하게 되는데, 보통은 소스관리에 포함하기를 원치 않을 것입니다. Git를 사용할 경우에는 .gitignore
파일에 이 파일을 추가해 주는 것이 좋습니다.
Spring과 명령들
zeus는 레일스 명령의 실행속도를 높이는 하나의 방법이지만 이것만이 있는 것은 아닙니다. 다른 선택 옵션들을 보도록 하겠습니다. 비슷한 툴로는 Spring이라는 것이 있으며 이 역시 레일스 어플리케이션을 미리 로딩해서 명령의 실행속도를 높여주지만 zeus와 차별되는 점이 몇가지 있습니다. gem install spring
명령으로 설치하면, zeus
명령과 매우 비슷하게 사용할 수 있는 spring
명령을 사용할 수 있게 됩니다. spring
명령으로 rails 와 rake 작업을 실행할 수 있지만, 한가지 차이점을 최초의 명령시에 백그라운에서 자동으로 레일스 어플리케이션을 시작한다는 것입니다. 이것이 의미하는 바는, spring을 통해서 실행하는 최초의 명령은, 레일스 어플리케이션이 시작하는데 걸리는 시간으로 인하여, 여전히 일정 시간이 소요된다는 것입니다. 이후 실행되는 명령은 이미 실행되어 있는 프로세스 상에서 실행되기 때문에 거의 즉각적으로 반응하게 됩니다.
spring을 사용하면, 전용 명령을 사용해서 레일스 어플리케이션을 시작할 필요가 없고, 언제라도 사용 중지하고자 한다면 단지 spring stop
명령을 실행하거나 터미널 세션을 종료하면 됩니다. spring의 또 다른 특정은 다양하게 옵션을 구성할 수 있다는 것입니다. 사전 로딩 방법과 주시할 디렉토리도 쉽게 변경할 수 있습니다. 그러나 파일 변경내용을 검토하기 위해서 디폴트로 fsevent를 사용하지 않고 1초에 5번 poll 을 한다는 것을 알아둘 필요가 있습니다. README를 보면 OS X을 사용할 경우 fsevent, 리눅스의 경우 inotify를 사용하기 위해 필요한 젬을 어플리케이션의 gemfile에 추가하는 것에 대한 설명을 볼 수 있습니다.
여기서 소개라 마지막 툴은 Commands라고 하는 것입니다. 이것은 레일스 어플리케이션을 미리 로드하지 않기 때문에 훨신 더 간단한 접근법이라 할 수 있습니다. 대신에 레일스 콘솔에서 레일스 명령을 실행할 수 있는 방법을 제공해 줍니다. 다른 두개의 툴과는 달리, 이 툴은 gemfile에 추가해서 bundle
명령을 시행하여 설치하게 됩니다.
gem 'commands', group: [:development, :test]
일단 설치된 후에는, 어플리케이션의 콘솔을 열고 여러가지 제너레이터와 rake 작업을 실행할 수 있게 됩니다.
>> generate "model author name" >> rake "db:migrate"
일단 어플리케이션이 콘솔에 로드되면 이와 같은 명령들은 매우 빠르게 실행될 것입니다. 불행이도 콘솔은 디폴트로 개발환경을 로드하기 때문에 테스트를 실행할 수 없습니다. 따라서 rails console test
명령을 실행해서 테스트 환경에서 콘솔을 열 필요가 있을 것입니다.
>> rake "db:migrate" >> test "functional"
테스트 전에 rake "db:migrate"
명령을 실행해서 테스트 데이터베이스가 마이그레이션이 되도록 했습니다. 이제 실행할 테스트 디렉토리를 명시해 주어 test
명령으로 테스트를 실행할 수 있게 됩니다. 디폴트로 보이는 결과창은 매우 복잡한데, 실행되는 SQL 명령들이 모두 보이기 때문입니다. 테스트를 실행하기 전 콘솔창에서 ActiveRecord::Base.logger = nil
명령을 실행하여 이와 같이 복잡하게 보이는 것을 없앨 수 있습니다. Commands는 RSpec 명령을 지원하지 않지만 향후 지원이 계획되어 있습니다.
285번 연제에서 다루었던 Spork를 간단하게 언급하면서 이번 연제를 마치도록 하겠습니다. 이것은 레일스를 미리 로딩하여 테스트 환경을 가속하기 위해 디자인되었고 이미 설명했던 다른 툴과 비슷한 방식으로 동작합니다. 현재 이것은 약간 시대에 뒤져 있고 다른 레일스 명령을 지원하지 않습니다. 다른 툴들이 원하는 바를 해결해 주지 않는 경우, 특히 윈도우 또는 Jruby를 사용할 경우, 고려할만 합니다.