ry / ebb fork watch download tarball
public this repo is viewable by everyone
Description: web server
Homepage: http://ebb.rubyforge.org
Clone URL: git://github.com/ry/ebb.git
Daemonizable fix-ups

Hacked around and simplified the Daemonizable include. For example, 
removed
the ability to change user, group - this is the job of the caller. Seems 
to
be functional now.
Ryan Dahl (author)
2 months ago
commit  05fac9f1f72ec39478d06178699d31fe8dd910e3
tree    091a9b8b93cdf1fe6706e3f6079e77fb265885bf
parent  55f770d3cc40a4c2a6d5b2005c48c52c1407c8d7
...
15
16
17
18
19
20
 
21
22
23
...
27
28
29
30
 
31
32
33
34
35
36
37
38
 
 
39
40
41
42
43
 
 
44
45
46
...
65
66
67
68
 
 
 
69
70
71
72
73
74
75
76
77
...
15
16
17
 
 
 
18
19
20
21
...
25
26
27
 
28
29
30
31
32
 
 
 
 
33
34
35
 
 
 
 
36
37
38
39
40
...
59
60
61
 
62
63
64
65
 
 
 
 
 
66
67
68
0
@@ -15,9 +15,7 @@ options = {
0
   :env => 'development',
0
   :hort => '0.0.0.0',
0
   :port => 3000,
0
- :timeout => 60,
0
- :log_file => 'log/ebb.log',
0
- :pid_file => 'tmp/pids/ebb.pid'
0
+ :timeout => 60
0
 }
0
 
0
 
0
@@ -27,20 +25,16 @@ opts = OptionParser.new do |opts|
0
   opts.separator ""
0
   opts.separator "Server options:"
0
 
0
- opts.on("-s", "--socket SOCKET", "listen on socket") { |socket| options[:socket] = socket }
0
+# opts.on("-s", "--socket SOCKET", "listen on socket") { |socket| options[:socket] = socket }
0
   opts.on("-p", "--port PORT", "use PORT (default: 3000)") { |port| options[:port] = port }
0
   opts.on("-e", "--env ENV", "Rails environment (default: development)") { |env| options[:env] = env }
0
   opts.on("-c", "--chdir PATH", "Rails root dir (default: current dir)") { |dir| options[:root] = dir }
0
   opts.on("-d", "--daemonize", "Daemonize") { options[:daemonize] = true }
0
- opts.on("-l", "--log-file FILE", "File to redirect output",
0
- "(default: #{options[:log_file]})") { |file| options[:log_file] = file }
0
- opts.on("-P", "--pid-file FILE", "File to store PID",
0
- "(default: #{options[:pid_file]})") { |file| options[:pid_file] = file }
0
+ opts.on("-l", "--log-file FILE", "File to redirect output") { |file| options[:log_file] = file }
0
+ opts.on("-P", "--pid-file FILE", "File to store PID") { |file| options[:pid_file] = file }
0
   opts.on("-t", "--timeout SEC", "Request or command timeout in sec",
0
- "(default: #{options[:timeout]})") { |sec| options[:timeout] = sec; raise NotImplementedError } # TODO: fix me
0
- opts.on("-u", "--user NAME", "User to run daemon as (use with -g)") { |user| options[:user] = user }
0
- opts.on("-g", "--group NAME", "Group to run daemon as (use with -u)") { |group| options[:group] = group }
0
-
0
+ "(default: #{options[:timeout]})") { |sec| options[:timeout] = sec }
0
+
0
   opts.separator ""
0
   opts.separator "Common options:"
0
 
0
@@ -65,13 +59,10 @@ when 'start'
0
   
0
   server.pid_file = options[:pid_file]
0
   server.log_file = options[:log_file]
0
- # server.timeout = options[:timeout]
0
+ server.timeout = options[:timeout]
0
+
0
+ server.daemonize if options[:daemonize]
0
   
0
- if options[:daemonize]
0
- server.change_privilege options[:user], options[:group] if options[:user] && options[:group]
0
- server.daemonize
0
- end
0
-
0
   server.start
0
 
0
 when 'stop'
...
1
2
 
3
4
5
...
29
30
31
32
 
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 
53
54
55
...
60
61
62
63
 
64
65
66
67
 
68
69
70
...
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
 
 
 
 
 
 
 
 
 
111
112
113
114
 
 
 
115
116
117
118
119
 
 
 
120
 
 
 
 
121
122
123
124
125
126
127
128
129
130
131
132
133
 
 
 
 
 
 
 
 
 
 
134
...
 
 
1
2
3
4
...
28
29
30
 
31
32
33
34
 
35
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
38
39
40
...
45
46
47
 
48
49
50
51
 
52
53
54
55
...
60
61
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
64
65
66
67
68
69
70
71
72
 
 
 
73
74
75
76
 
 
 
 
77
78
79
80
81
82
83
84
85
86
87
 
 
 
 
 
 
 
 
 
 
88
89
90
91
92
93
94
95
96
97
98
0
@@ -1,5 +1,4 @@
0
-# Copyright (c) 2007 Marc-André Cournoyer
0
-require 'etc'
0
+# Simplified version of Thin::Daemonizable by Marc-André Cournoyer
0
 
0
 module Kernel
0
   unless respond_to? :daemonize # Already part of Ruby 1.9, yeah!
0
@@ -29,27 +28,13 @@ module Process
0
   module_function :running?
0
 end
0
 
0
-# Module included in classes that can be turned into a daemon.
0
+# Moadule included in classes that can be turned into a daemon.
0
 # Handle stuff like:
0
 # * storing the PID in a file
0
 # * redirecting output to the log file
0
-# * changing processs privileges
0
 # * killing the process gracefully
0
 module Daemonizable
0
- attr_accessor :pid_file, :log_file
0
-
0
- def self.included(base)
0
- base.extend ClassMethods
0
- end
0
-
0
- def daemonizable_init(options)
0
- @pid_file = options[:pid_file]
0
- @log_file = options[:log_file]
0
- if options[:daemonize]
0
- change_privilege options[:user], options[:group] if options[:user] && options[:group]
0
- daemonize
0
- end
0
- end
0
+ attr_accessor :pid_file, :log_file, :timeout
0
   
0
   def pid
0
     File.exist?(pid_file) ? open(pid_file).read : nil
0
@@ -60,11 +45,11 @@ module Daemonizable
0
     raise ArgumentError, 'You must specify a pid_file to deamonize' unless @pid_file
0
     
0
     pwd = Dir.pwd # Current directory is changed during daemonization, so store it
0
- super # Calls Kernel#daemonize
0
+ Kernel.daemonize
0
     Dir.chdir pwd
0
     
0
     trap('HUP', 'IGNORE') # Don't die upon logout
0
-
0
+
0
     # Redirect output to the logfile
0
     [STDOUT, STDERR].each { |f| f.reopen @log_file, 'a' } if @log_file
0
     
0
@@ -75,60 +60,39 @@ module Daemonizable
0
     end
0
   end
0
   
0
- # Change privileges of the process
0
- # to the specified user and group.
0
- def change_privilege(user, group=user)
0
- log ">> Changing process privilege to #{user}:#{group}"
0
-
0
- uid, gid = Process.euid, Process.egid
0
- target_uid = Etc.getpwnam(user).uid
0
- target_gid = Etc.getgrnam(group).gid
0
-
0
- if uid != target_uid || gid != target_gid
0
- # Change process ownership
0
- Process.initgroups(user, target_gid)
0
- Process::GID.change_privilege(target_gid)
0
- Process::UID.change_privilege(target_uid)
0
- end
0
- rescue Errno::EPERM => e
0
- log "Couldn't change user and group to #{user}:#{group}: #{e}"
0
- end
0
-
0
- module ClassMethods
0
- # Kill the process which PID is stored in +pid_file+.
0
- def kill(pid_file, timeout=60)
0
- if pid = open(pid_file).read
0
- pid = pid.to_i
0
- print "Sending INT signal to process #{pid} ... "
0
- begin
0
- Process.kill('INT', pid)
0
- Timeout.timeout(timeout) do
0
- sleep 0.1 while Process.running?(pid)
0
- end
0
- rescue Timeout::Error
0
- print "timeout, Sending KILL signal ... "
0
- Process.kill('KILL', pid)
0
+ # Kill the process which PID is stored in +pid_file+.
0
+ def self.kill(pid_file, timeout=60)
0
+ if pid = open(pid_file).read
0
+ pid = pid.to_i
0
+ print "Sending INT signal to process #{pid} ... "
0
+ begin
0
+ Process.kill('INT', pid)
0
+ Timeout.timeout(timeout) do
0
+ sleep 0.1 while Process.running?(pid)
0
         end
0
- puts "stopped!"
0
- else
0
- puts "Can't stop process, no PID found in #{@pid_file}"
0
+ rescue Timeout::Error
0
+ print "timeout, Sending KILL signal ... "
0
+ Process.kill('KILL', pid)
0
       end
0
- rescue Errno::ESRCH # No such process
0
- puts "process not found!"
0
- ensure
0
- File.delete(pid_file) rescue nil
0
+ puts "stopped!"
0
+ else
0
+ puts "Can't stop process, no PID found in #{@pid_file}"
0
     end
0
+ rescue Errno::ESRCH # No such process
0
+ puts "process not found!"
0
+ ensure
0
+ File.delete(pid_file) rescue nil
0
   end
0
   
0
   private
0
- def remove_pid_file
0
- File.delete(@pid_file) if @pid_file && File.exists?(@pid_file)
0
- end
0
-
0
- def write_pid_file
0
- log ">> Writing PID to #{@pid_file}"
0
- FileUtils.mkdir_p File.dirname(@pid_file)
0
- open(@pid_file,"w") { |f| f.write(Process.pid) }
0
- File.chmod(0644, @pid_file)
0
- end
0
+
0
+ def remove_pid_file
0
+ File.delete(@pid_file) if @pid_file && File.exists?(@pid_file)
0
+ end
0
+
0
+ def write_pid_file
0
+ log ">> Writing PID to #{@pid_file}"
0
+ open(@pid_file,"w+") { |f| f.write(Process.pid) }
0
+ File.chmod(0644, @pid_file)
0
+ end
0
 end
...
73
74
75
76
77
78
79
80
81
...
73
74
75
 
 
 
76
77
78
0
@@ -73,9 +73,6 @@ module Ebb
0
       @port = (options[:port] || 4001).to_i
0
       @timeout = options[:timeout]
0
       @app = app
0
-
0
- daemonizable_init(options)
0
- # FFI::server_initialize(self)
0
     end
0
     
0
     def start
...
8
9
10
 
11
12
13
...
120
121
122
 
 
 
 
 
 
 
 
 
 
 
 
123
124
125
 
 
126
127
128
...
8
9
10
11
12
13
14
...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
0
@@ -8,6 +8,7 @@ class EbbTest < Test::Unit::TestCase
0
   def setup
0
     @pid = fork do
0
       server = Ebb::Server.new(self, :port => 4044)
0
+ STDOUT.reopen "/dev/null", "a"
0
       server.start
0
     end
0
     sleep 0.5
0
@@ -120,9 +121,23 @@ class EbbRailsTest < Test::Unit::TestCase
0
     out = %x{ruby #{Ebb::LIBDIR}/../bin/ebb_rails -v}
0
     assert_match %r{Ebb #{Ebb::VERSION}}, out
0
   end
0
+
0
+ # def get(path)
0
+ # Net::HTTP.get_response(URI.parse("http://0.0.0.0:4043#{path}"))
0
+ # end
0
+ #
0
+ # def test_starting_with_many_options
0
+ # %x{cd /tmp && rails ebb_test && ruby #{Ebb::LIBDIR}/../bin/ebb_rails start -d -e development -c /tmp/ebb_test -u www -g www -P /tmp/ebb.1.pid -p 4043 &}
0
+ # response = get('/')
0
+ # assert_equal 200, response.code
0
+ # ensure
0
+ # Process.kill('KILL', %x{cat /tmp/ebb.1.pid})
0
+ # end
0
 end
0
 
0
 
0
+
0
+
0
 #
0
 # class SocketTest < Test::Unit::TestCase
0
 # def test_socket_creation

Comments

    No one has commented yet.