Search code examples
rubybundlerdaemonthin

thin starts two ruby processes per server, kills wrong one


I'm starting up three thin processes with bundle exec thin start -C /etc/thin/staging.yml

I use rvm, ruby version is ree-1.8.7

Contents of /etc/thin/staging.yml:

---                                                             
timeout: 30                                                     
pid: /home/myuser/apps/g/shared/pids/thin.pid           
max_persistent_conns: 512                                       
servers: 3                                                      
chdir: /home/myuser/apps/g/current                      
port: 3040                                                      
require: []                                                     

log: /home/myuser/apps/g/shared/log/thin.log            
daemonize: true                                                 
address: 0.0.0.0                                                
max_conns: 1024                                                 
wait: 30                                                        
environment: staging                                            

lsof -i :3040-3042 will show three ruby processes listening on ports 3040-3042, but the pid files contain three different (slightly lower) pids. All six processes are called merb : merb : Master

When I stop thin with bundle exec thin stop -C /etc/thin/staging.yml, thin first sends a QUIT signal to the processes in the pid files, then, after a timeout, a KILL signal.

The pid files are now gone, the thin logs show that the server has stopped, but there are still three ruby processes listening on ports 3040-3042, so a subsequent thin start will fail.

The only differences between the output of lsof -p of both processes is a /lib/libnss_files-2.12.so library and a postgres socket.

My questions are:

  • why do I get a timeout during thin stop?
  • why are there two processes per server instead of one?
  • how do I fix this elegantly (without kill -9)

Solution

  • Apparently the Merb bootloader does a fork. How braindead is that!

    Set Merb::Config[:fork_for_class_load] = false in your config.ru.