rails passenger development environment

一直以来,我在开发rails程序的时候,都是使用rails自带的webrick server,而在部署rails程序的时候使用passenger。

一般来说,passenger是用来做production环境下的rails server,但是railscasts上有一个叫做passenger development的片段,讲的是用passenger(mod_rails)来做开发环境下的rails server。

使用passenger来做开发环境下的server,其好处是可以同时构架多个app的开发环境,免去了对于每个app都得开一个terminal,然后使用webrick的方式。

下面比较一下二者:

  1. 同时对多个本地app进行开发时,passenger比webrick好。因为不需要对于每个app都开一个webrick server,而且对于每个server还需要指定不同的port。
  2. 在查看request的信息方面,passenger和webrick差不多。webrick是直接在terminal中显示每个request的信息;而在使用passenger时,则可以通过动态显示development.log的方式进行查看。
  3. 在debug方面,webrick会比passenger方便些。在使用webrick时,只需要使用u option来启动server,那么app就会在运行时中断在程序中写有debugger语句的地方。可是,在使用passenger时,debug可能会比较麻烦。目前看到的有两种方式,一种是通过使用remote debug的方式,具体可以参考Passenger (mod_rails) for development. Now with debugger! 。另一种是使用rack-debug,它是一个ruby-debug的interface,其使用方式和webrick没有多大区别,但是唯一一点令我难受的时,对于每个rails app,都需要添加一个middleware来实现rack-debug的功能,但是由于可以通过version control在真正的app里过滤掉这些文件,其实并没有多大影响。

所以经过比较,我觉得可以先对rack-debug作一些尝试。

add starling boot service to ubuntu

在做rails的项目时,需要在系统启动的时候自动启动两个进程,如何在ubuntu中添加自启动的进程,过程是很简单的。有一下两个步骤:

  1. 仿照/etc/init.d/中的任何一个文件,根据自己的进程需要,创建一个系统启动时用的script。比如说这次我想作的是让starling在系统启动时自动启动运行,仿制的script如下(当然,script在运行是需要的各种资源,比如用户,用户组,目录等等都需要事先建好才行):
#! /bin/sh
### BEGIN INIT INFO
# Provides: starling
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: S 0 1 6
# Short-Description: Starling queue server
# Description: The Starling distributed, transactional queue server
### END INIT INFO
# Author: Twitter
# Version: 0.10.0
 
set -e
 
LOGFILE=/var/log/starling/starling.log
SPOOLDIR=/var/spool/starling
PORT=15151
LISTEN=127.0.0.1
PIDFILE=/var/run/starling/starling.pid
 
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=starling
DESC="Starling"
INSTALL_DIR=/usr/bin
DAEMON=$INSTALL_DIR/$NAME
SCRIPTNAME=/etc/init.d/$NAME
OPTS="-h $LISTEN -p $PORT -d -q $SPOOLDIR -P $PIDFILE -L $LOGFILE"
 
. /lib/lsb/init-functions
 
# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0
 
d_start() {
        log_begin_msg "Starting Starling Server..."
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- $OPTS \
        || log_end_msg 1
        log_end_msg 0
}
 
d_stop() {
        log_begin_msg "Stopping Starling Server..."
        start-stop-daemon --stop --quiet --pidfile $PIDFILE \
        || log_end_msg 1
        log_end_msg 0
}
 
case "$1" in
start)
d_start
;;
stop)
d_stop
;;
restart|force-reload|reload)
d_stop
sleep 2
d_start
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
 
exit 0
  1. 用update-rc.d命令将创建好的script添加到系统启动的各个过程之中。比如:
# update-rc.d some.scripts defaults

Using Synergykm to share keyboard/mouse between two macs(US keyboard and JIS keyboard)

I have two mac computers in my lab and it is quite inconvenient to use two sets of keyboard/mouse, so I tried to use synergykm to share one set between these two macs.

Synergykm is a mac style wrapper of synergy which is an open source package aiming at sharing keyboard/mouse between all types of systems.

Generally it is quite easy to use synergykm or synergy to share keyboard/mouse if one’s keyboards are all in the same layout. Unfortunately, in my case, I have a imac which has US keyboard layout and a macbook which has JIS keyboard layout.

So after setting the imac as server and sharing its keyboard/mouse to the client macbook, everything went well except that I could not type underscore, backslash and pipe character in the client macbook by using the server’s US keyboard.

The problem occured when sharing a US layout keyboard to a JIS layout keyboard macbbook.

Luckly, I find this software called JANSI, which can change the JIS layout macbook to an US layout macbook. So after applying JANSI, I can easily sharing keyboard/mouse between US layout imac and JIS layout macbook.

Reference:

  1. Synergyのキーボード配列の国際化問題
  2. JANSI

rake:migrate failed when loading observer in enrivonment.rb

在使用rails时,如果在enrivonment.rb文件中用下面的语句打开了使用observer的开关

config.active_record.observers = :xxx

此时在执行rake db:migrate VERSION=0的时候,会遇到数据库错误的情况

rake aborted! Mysql::Error: Table 'xxx_development.yyy' doesn't exist: SHOW FIELDS FROM `yyy`

其原因是,rake db:migrate的执行需要load environment,可是environment又是需要load observer,可是与数据库关联的在observer中的表格此时还未存在,所以造成了错误的出现。

解决方法需要在environment.rb中,通过下面的设置使在执行rake db:migrate的时候不要load observer

unless (File.basename($0) == 'rake' && ARGV.include?('db:migrate'))
  config.active_record.observers = :xxx
end

capistrano的设置问题

当SCM的repositoty和需要部署的app都在同一台服务器上的时候,可以在capistrano的设置文件中用下面的方式使之从本地拷贝代码。

set :repository, "/scm/repository/direcoty/on/server/xxx.git"
set :local_repository, "ssh://xxx.xxx.xxx.xxx/scm/repository/direcoty/on/server/xxx.git"