thin 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of thin might be problematic. Click here for more details.

Files changed (91) hide show
  1. data/COPYING +18 -0
  2. data/README +32 -45
  3. data/Rakefile +66 -23
  4. data/bin/thin +76 -45
  5. data/doc/benchmarks.txt +64 -249
  6. data/doc/rdoc/created.rid +1 -1
  7. data/doc/rdoc/files/README.html +37 -100
  8. data/doc/rdoc/rdoc-style.css +5 -0
  9. data/example/config.ru +9 -0
  10. data/ext/thin_parser/common.rl +54 -0
  11. data/ext/thin_parser/ext_help.h +14 -0
  12. data/ext/thin_parser/extconf.rb +6 -0
  13. data/ext/thin_parser/parser.c +1199 -0
  14. data/ext/thin_parser/parser.h +49 -0
  15. data/ext/thin_parser/parser.rl +143 -0
  16. data/ext/thin_parser/thin.c +424 -0
  17. data/lib/rack/adapter/rails.rb +136 -0
  18. data/lib/rack/handler/thin.rb +13 -0
  19. data/lib/thin.rb +28 -12
  20. data/lib/thin/connection.rb +47 -0
  21. data/lib/thin/daemonizing.rb +5 -1
  22. data/lib/thin/headers.rb +3 -2
  23. data/lib/thin/logging.rb +6 -13
  24. data/lib/thin/request.rb +53 -133
  25. data/lib/thin/response.rb +21 -25
  26. data/lib/thin/server.rb +30 -94
  27. data/lib/thin/version.rb +2 -2
  28. data/lib/thin_parser.bundle +0 -0
  29. data/spec/daemonizing_spec.rb +94 -0
  30. data/spec/headers_spec.rb +35 -0
  31. data/spec/request_spec.rb +258 -0
  32. data/spec/response_spec.rb +40 -0
  33. data/spec/server_spec.rb +75 -0
  34. data/spec/spec_helper.rb +126 -0
  35. metadata +79 -99
  36. data/bin/thin_cluster +0 -53
  37. data/doc/rdoc/classes/Kernel.html +0 -182
  38. data/doc/rdoc/classes/Process.html +0 -175
  39. data/doc/rdoc/classes/Thin.html +0 -184
  40. data/doc/rdoc/classes/Thin/CGIWrapper.html +0 -438
  41. data/doc/rdoc/classes/Thin/Cluster.html +0 -392
  42. data/doc/rdoc/classes/Thin/Command.html +0 -221
  43. data/doc/rdoc/classes/Thin/CommandError.html +0 -154
  44. data/doc/rdoc/classes/Thin/Commands.html +0 -145
  45. data/doc/rdoc/classes/Thin/Daemonizable.html +0 -250
  46. data/doc/rdoc/classes/Thin/Daemonizable/ClassMethods.html +0 -203
  47. data/doc/rdoc/classes/Thin/DirHandler.html +0 -250
  48. data/doc/rdoc/classes/Thin/Handler.html +0 -195
  49. data/doc/rdoc/classes/Thin/Headers.html +0 -244
  50. data/doc/rdoc/classes/Thin/InvalidRequest.html +0 -150
  51. data/doc/rdoc/classes/Thin/Logging.html +0 -214
  52. data/doc/rdoc/classes/Thin/RailsHandler.html +0 -234
  53. data/doc/rdoc/classes/Thin/RailsServer.html +0 -175
  54. data/doc/rdoc/classes/Thin/Request.html +0 -379
  55. data/doc/rdoc/classes/Thin/Response.html +0 -311
  56. data/doc/rdoc/classes/Thin/Server.html +0 -381
  57. data/doc/rdoc/files/bin/thin.html +0 -188
  58. data/doc/rdoc/files/bin/thin_cluster.html +0 -175
  59. data/doc/rdoc/files/lib/thin/cgi_rb.html +0 -263
  60. data/doc/rdoc/files/lib/thin/cluster_rb.html +0 -263
  61. data/doc/rdoc/files/lib/thin/command_rb.html +0 -263
  62. data/doc/rdoc/files/lib/thin/consts_rb.html +0 -263
  63. data/doc/rdoc/files/lib/thin/daemonizing_rb.html +0 -263
  64. data/doc/rdoc/files/lib/thin/handler_rb.html +0 -263
  65. data/doc/rdoc/files/lib/thin/headers_rb.html +0 -263
  66. data/doc/rdoc/files/lib/thin/logging_rb.html +0 -263
  67. data/doc/rdoc/files/lib/thin/mime_types_rb.html +0 -263
  68. data/doc/rdoc/files/lib/thin/rails_rb.html +0 -263
  69. data/doc/rdoc/files/lib/thin/recipes_rb.html +0 -171
  70. data/doc/rdoc/files/lib/thin/request_rb.html +0 -171
  71. data/doc/rdoc/files/lib/thin/response_rb.html +0 -171
  72. data/doc/rdoc/files/lib/thin/server_rb.html +0 -171
  73. data/doc/rdoc/files/lib/thin/statuses_rb.html +0 -171
  74. data/doc/rdoc/files/lib/thin/version_rb.html +0 -171
  75. data/lib/thin/cgi.rb +0 -159
  76. data/lib/thin/cluster.rb +0 -147
  77. data/lib/thin/command.rb +0 -49
  78. data/lib/thin/commands/cluster/base.rb +0 -24
  79. data/lib/thin/commands/cluster/config.rb +0 -36
  80. data/lib/thin/commands/cluster/restart.rb +0 -35
  81. data/lib/thin/commands/cluster/start.rb +0 -40
  82. data/lib/thin/commands/cluster/stop.rb +0 -28
  83. data/lib/thin/commands/server/base.rb +0 -7
  84. data/lib/thin/commands/server/start.rb +0 -33
  85. data/lib/thin/commands/server/stop.rb +0 -29
  86. data/lib/thin/consts.rb +0 -37
  87. data/lib/thin/handler.rb +0 -57
  88. data/lib/thin/mime_types.rb +0 -619
  89. data/lib/thin/rails.rb +0 -44
  90. data/lib/thin/recipes.rb +0 -36
  91. data/lib/transat/parser.rb +0 -247
@@ -1,171 +0,0 @@
1
-
2
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
3
- <html>
4
- <head>
5
- <title>
6
- thin &raquo; File: version.rb
7
- </title>
8
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
9
- <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
10
- <script language="JavaScript" type="text/javascript">
11
- // <![CDATA[
12
-
13
- function toggleSource( id )
14
- {
15
- var elem
16
- var link
17
-
18
- if( document.getElementById )
19
- {
20
- elem = document.getElementById( id )
21
- link = document.getElementById( "l_" + id )
22
- }
23
- else if ( document.all )
24
- {
25
- elem = eval( "document.all." + id )
26
- link = eval( "document.all.l_" + id )
27
- }
28
- else
29
- return false;
30
-
31
- if( elem.style.display == "block" )
32
- {
33
- elem.style.display = "none"
34
- link.innerHTML = "show source"
35
- }
36
- else
37
- {
38
- elem.style.display = "block"
39
- link.innerHTML = "hide source"
40
- }
41
- }
42
-
43
- function openCode( url )
44
- {
45
- window.open( url, "SOURCE_CODE", "width=400,height=400,scrollbars=yes" )
46
- }
47
- // ]]>
48
- </script>
49
- </head>
50
- <body>
51
- <ul id="menu">
52
- <li><a href="/thin/">home</a></li>
53
- <li><a href="/thin/doc/">doc</a></li>
54
- <li><a href="/thin/trac.fcgi/timeline">timeline</a></li>
55
- <li><a href="/thin/trac.fcgi/browser">code</a></li>
56
- <li><a href="/thin/trac.fcgi/report">tickets</a></li>
57
- <li><a href="/thin/trac.fcgi/newticket">new ticket</a></li>
58
- </ul>
59
- <div id="sidebar">
60
- <h2>Files</h2>
61
- <ul class="list">
62
- <li><a href="../../../files/README.html" value="File: README">README</a></li>
63
- <li><a href="../../../files/lib/thin/cgi_rb.html" value="File: cgi.rb">lib/thin/cgi.rb</a></li>
64
- <li><a href="../../../files/lib/thin/cluster_rb.html" value="File: cluster.rb">lib/thin/cluster.rb</a></li>
65
- <li><a href="../../../files/lib/thin/command_rb.html" value="File: command.rb">lib/thin/command.rb</a></li>
66
- <li><a href="../../../files/lib/thin/consts_rb.html" value="File: consts.rb">lib/thin/consts.rb</a></li>
67
- <li><a href="../../../files/lib/thin/daemonizing_rb.html" value="File: daemonizing.rb">lib/thin/daemonizing.rb</a></li>
68
- <li><a href="../../../files/lib/thin/handler_rb.html" value="File: handler.rb">lib/thin/handler.rb</a></li>
69
- <li><a href="../../../files/lib/thin/headers_rb.html" value="File: headers.rb">lib/thin/headers.rb</a></li>
70
- <li><a href="../../../files/lib/thin/logging_rb.html" value="File: logging.rb">lib/thin/logging.rb</a></li>
71
- <li><a href="../../../files/lib/thin/mime_types_rb.html" value="File: mime_types.rb">lib/thin/mime_types.rb</a></li>
72
- <li><a href="../../../files/lib/thin/rails_rb.html" value="File: rails.rb">lib/thin/rails.rb</a></li>
73
- <li><a href="../../../files/lib/thin/recipes_rb.html" value="File: recipes.rb">lib/thin/recipes.rb</a></li>
74
- <li><a href="../../../files/lib/thin/request_rb.html" value="File: request.rb">lib/thin/request.rb</a></li>
75
- <li><a href="../../../files/lib/thin/response_rb.html" value="File: response.rb">lib/thin/response.rb</a></li>
76
- <li><a href="../../../files/lib/thin/server_rb.html" value="File: server.rb">lib/thin/server.rb</a></li>
77
- <li><a href="../../../files/lib/thin/statuses_rb.html" value="File: statuses.rb">lib/thin/statuses.rb</a></li>
78
- <li><a href="../../../files/lib/thin/version_rb.html" value="File: version.rb">lib/thin/version.rb</a></li>
79
- <li><a href="../../../files/bin/thin.html" value="File: thin">bin/thin</a></li>
80
- <li><a href="../../../files/bin/thin_cluster.html" value="File: thin_cluster">bin/thin_cluster</a></li>
81
- </ul>
82
-
83
- <h2>Classes</h2>
84
- <ul class="list">
85
- <li><a href="../../../classes/Thin.html" title="Module: Thin">Thin</a></li>
86
- <li><a href="../../../classes/Thin/Commands.html" title="Module: Thin::Commands">Thin::Commands</a></li>
87
- <li><a href="../../../classes/Thin/Daemonizable.html" title="Module: Thin::Daemonizable">Thin::Daemonizable</a></li>
88
- <li><a href="../../../classes/Thin/Daemonizable/ClassMethods.html" title="Module: Thin::Daemonizable::ClassMethods">Thin::Daemonizable::ClassMethods</a></li>
89
- <li><a href="../../../classes/Thin/VERSION.html" title="Module: Thin::VERSION">Thin::VERSION</a></li>
90
- <li><a href="../../../classes/Thin/Logging.html" title="Module: Thin::Logging">Thin::Logging</a></li>
91
- <li><a href="../../../classes/Thin/DirHandler.html" title="Class: Thin::DirHandler">Thin::DirHandler</a></li>
92
- <li><a href="../../../classes/Thin/InvalidRequest.html" title="Class: Thin::InvalidRequest">Thin::InvalidRequest</a></li>
93
- <li><a href="../../../classes/Thin/CGIWrapper.html" title="Class: Thin::CGIWrapper">Thin::CGIWrapper</a></li>
94
- <li><a href="../../../classes/Thin/Command.html" title="Class: Thin::Command">Thin::Command</a></li>
95
- <li><a href="../../../classes/Thin/Response.html" title="Class: Thin::Response">Thin::Response</a></li>
96
- <li><a href="../../../classes/Thin/Headers.html" title="Class: Thin::Headers">Thin::Headers</a></li>
97
- <li><a href="../../../classes/Thin/Server.html" title="Class: Thin::Server">Thin::Server</a></li>
98
- <li><a href="../../../classes/Thin/CommandError.html" title="Class: Thin::CommandError">Thin::CommandError</a></li>
99
- <li><a href="../../../classes/Thin/Request.html" title="Class: Thin::Request">Thin::Request</a></li>
100
- <li><a href="../../../classes/Thin/RailsServer.html" title="Class: Thin::RailsServer">Thin::RailsServer</a></li>
101
- <li><a href="../../../classes/Thin/Cluster.html" title="Class: Thin::Cluster">Thin::Cluster</a></li>
102
- <li><a href="../../../classes/Thin/RailsHandler.html" title="Class: Thin::RailsHandler">Thin::RailsHandler</a></li>
103
- <li><a href="../../../classes/Thin/Handler.html" title="Class: Thin::Handler">Thin::Handler</a></li>
104
- <li><a href="../../../classes/Process.html" title="Module: Process">Process</a></li>
105
- <li><a href="../../../classes/Kernel.html" title="Module: Kernel">Kernel</a></li>
106
- </ul>
107
- </div>
108
- <div id="container">
109
- <div id="header">
110
- <a href="/thin/" title="Home">
111
- <img id="logo" src="../../../logo.gif" />
112
- </a>
113
- <h2 id="tag_line">A fast and very simple Ruby web server</h2>
114
- </div>
115
-
116
- <div id="content">
117
- <h2>File: version.rb</h2>
118
-
119
- <div id="lib/thin/version.rb" class="page_shade">
120
- <div class="page">
121
- <div class="header">
122
- <div class="path">lib/thin/version.rb / Tue Dec 04 15:08:56 -0500 2007</div>
123
- </div>
124
-
125
- <h2>Set of Capistrano 2 recipes</h2>
126
- <p>
127
- To use, add on top of your Capfile file:
128
- </p>
129
- <pre>
130
- load 'config/deploy'
131
- # ...
132
- require 'thin'
133
- require 'thin/recipes'
134
- </pre>
135
- <h3>Configurable parameters</h3>
136
- <p>
137
- You can configure some parameters but it should work out of the box. Path
138
- to the thin_cluster script, don&#8216;t need to change this if you
139
- installed thin as a gem on the server.
140
- </p>
141
- <pre>
142
- set :thin_cluster, &quot;thin_cluster&quot;
143
- </pre>
144
- <p>
145
- Location of the config file:
146
- </p>
147
- <pre>
148
- set :thin_config, &quot;#{release_path}/config/thin.yml&quot;
149
- </pre>
150
-
151
-
152
- <strong>Requires:</strong>
153
- socket
154
- </ul>
155
-
156
-
157
-
158
-
159
-
160
- </div>
161
- </div>
162
-
163
-
164
- </div>
165
- </div>
166
- <div id="footer">
167
- <hr />
168
- &copy; <a href="http://macournoyer.com">Marc-Andr&eacute; Cournoyer</a>
169
- </div>
170
- </body>
171
- </html>
@@ -1,159 +0,0 @@
1
- require 'cgi'
2
-
3
- module Thin
4
- # Class largely based on Mongrel::CGIWrapper
5
- # http://mongrel.rubyforge.org by Zed A. Shaw <zedshaw at zedshaw dot com>
6
- class CGIWrapper < ::CGI
7
- public :env_table
8
- attr_reader :options
9
- # Set this to false if you want calls to CGIWrapper.out to not actually send
10
- # the response until you force it.
11
- attr_accessor :default_really_final
12
-
13
- # these are stripped out of any keys passed to CGIWrapper.header function
14
- REMOVED_KEYS = [ "nph","status","server","connection","type",
15
- "charset","length","language","expires"]
16
-
17
- # Takes an HttpRequest and HttpResponse object, plus any additional arguments
18
- # normally passed to CGI. These are used internally to create a wrapper around
19
- # the real CGI while maintaining Mongrel's view of the world.
20
- def initialize(request, response, *args)
21
- @request = request
22
- @response = response
23
- @args = *args
24
- @input = request.body
25
- @head = {}
26
- @out_called = false
27
- @default_really_final = true
28
- super(*args)
29
- end
30
-
31
- # The header is typically called to send back the header. In our case we
32
- # collect it into a hash for later usage.
33
- #
34
- # nph -- Mostly ignored. It'll output the date.
35
- # connection -- Completely ignored. Why is CGI doing this?
36
- # length -- Ignored since Mongrel figures this out from what you write to output.
37
- #
38
- def header(options = "text/html")
39
- # if they pass in a string then just write the Content-Type
40
- if options.class == String
41
- @head['Content-Type'] = options unless @head['Content-Type']
42
- else
43
- # convert the given options into what Mongrel wants
44
- @head['Content-Type'] = options['type'] || "text/html"
45
- @head['Content-Type'] += "; charset=" + options['charset'] if options.has_key? "charset" if options['charset']
46
-
47
- # setup date only if they use nph
48
- @head['Date'] = CGI::rfc1123_date(Time.now) if options['nph']
49
-
50
- # setup the server to use the default or what they set
51
- @head['Server'] = options['server'] || env_table['SERVER_SOFTWARE']
52
-
53
- # remaining possible options they can give
54
- @head['Status'] = options['status'] if options['status']
55
- @head['Content-Language'] = options['language'] if options['language']
56
- @head['Expires'] = options['expires'] if options['expires']
57
-
58
- # drop the keys we don't want anymore
59
- REMOVED_KEYS.each {|k| options.delete(k) }
60
-
61
- # finally just convert the rest raw (which puts 'cookie' directly)
62
- # 'cookie' is translated later as we write the header out
63
- options.each{|k,v| @head[k] = v}
64
- end
65
-
66
- # doing this fakes out the cgi library to think the headers are empty
67
- # we then do the real headers in the out function call later
68
- ""
69
- end
70
-
71
- # Takes any 'cookie' setting and sends it over the Mongrel header,
72
- # then removes the setting from the options. If cookie is an
73
- # Array or Hash then it sends those on with .to_s, otherwise
74
- # it just calls .to_s on it and hopefully your "cookie" can
75
- # write itself correctly.
76
- def send_cookies(to)
77
- # convert the cookies based on the myriad of possible ways to set a cookie
78
- if @head['cookie']
79
- cookie = @head['cookie']
80
- case cookie
81
- when Array
82
- cookie.each {|c| to['Set-Cookie'] = c.to_s }
83
- when Hash
84
- cookie.each_value {|c| to['Set-Cookie'] = c.to_s}
85
- else
86
- to['Set-Cookie'] = options['cookie'].to_s
87
- end
88
-
89
- @head.delete('cookie')
90
- end
91
-
92
- # @output_cookies seems to never be used, but we'll process it just in case
93
- @output_cookies.each {|c| to['Set-Cookie'] = c.to_s } if @output_cookies
94
- end
95
-
96
- # The dumb thing is people can call header or this or both and in any order.
97
- # So, we just reuse header and then finalize the HttpResponse the right way.
98
- # Status is taken from the various options and converted to what Mongrel needs
99
- # via the CGIWrapper.status function.
100
- #
101
- # We also prevent Rails from actually doing the final send by adding a
102
- # second parameter "really_final". Only Mongrel calls this after Rails
103
- # is done. Since this will break other frameworks, it defaults to
104
- # a different setting for rails (false) and (true) for others.
105
- def out(options = "text/html", really_final=@default_really_final)
106
- if @out_called || !really_final
107
- # don't do it more than once or if it's not the really final call
108
- return
109
- end
110
-
111
- header(options)
112
-
113
- @response.start status do |head, body|
114
- send_cookies(head)
115
-
116
- @head.each {|k,v| head[k] = v}
117
- body.write(yield || "")
118
- end
119
-
120
- @out_called = true
121
- end
122
-
123
- # Computes the status once, but lazily so that people who call header twice
124
- # don't get penalized. Because CGI insists on including the options status
125
- # message in the status we have to do a bit of parsing.
126
- def status
127
- if not @status
128
- stat = @head["Status"]
129
- stat = stat.split(' ')[0] if stat
130
-
131
- @status = stat || "200"
132
- end
133
-
134
- @status
135
- end
136
-
137
- # Used to wrap the normal args variable used inside CGI.
138
- def args
139
- @args
140
- end
141
-
142
- # Used to wrap the normal env_table variable used inside CGI.
143
- def env_table
144
- @request.params
145
- end
146
-
147
- # Used to wrap the normal stdinput variable used inside CGI.
148
- def stdinput
149
- @input
150
- end
151
-
152
- # The stdoutput should be completely bypassed but we'll drop a warning just in case
153
- def stdoutput
154
- STDERR.puts "WARNING: Your program is doing something not expected. Please tell Zed that stdoutput was used and what software you are running. Thanks."
155
- @response.body
156
- end
157
-
158
- end
159
- end
@@ -1,147 +0,0 @@
1
- module Thin
2
- # Control a set of servers. Generate start and stop commands and run them.
3
- class Cluster
4
- include Logging
5
-
6
- attr_accessor :environment, :log_file, :pid_file, :user, :group, :timeout
7
- attr_reader :address, :first_port, :size
8
-
9
- # Script to run
10
- def self.thin=(value)
11
- @@thin = value
12
- end
13
- @@thin = 'thin'
14
-
15
- # Create a new cluster of servers bound to +host+
16
- # on ports +first_port+ to <tt>first_port + size - 1</tt>.
17
- def initialize(dir, address, first_port, size)
18
- @address = address
19
- @first_port = first_port
20
- @size = size
21
-
22
- @log_file = 'thin.log'
23
- @pid_file = 'thin.pid'
24
-
25
- @timeout = 60 # sec
26
-
27
- Dir.chdir dir if dir
28
- end
29
-
30
- # Start the servers
31
- def start
32
- with_each_instance do |port|
33
- start_on_port port
34
- end
35
- end
36
-
37
- # Start the server on a single port
38
- def start_on_port(port)
39
- logc "Starting #{address}:#{port} ... "
40
-
41
- run :start, :port => port,
42
- :address => @address,
43
- :environment => @environment,
44
- :daemonize => true,
45
- :pid_file => pid_file_for(port),
46
- :log_file => log_file_for(port),
47
- :user => @user,
48
- :group => @group,
49
- :timeout => @timeout,
50
- :trace => @trace
51
-
52
- if wait_until_pid(:exist, port)
53
- log "started in #{pid_for(port)}" if $?.success?
54
- else
55
- log 'failed to start'
56
- end
57
- end
58
-
59
- # Stop the servers
60
- def stop
61
- with_each_instance do |port|
62
- stop_on_port port
63
- end
64
- end
65
-
66
- # Stop the server running on +port+
67
- def stop_on_port(port)
68
- logc "Stopping #{address}:#{port} ... "
69
-
70
- run :stop, :pid_file => pid_file_for(port),
71
- :timeout => @timeout
72
-
73
- if wait_until_pid(!:exist, port)
74
- log 'stopped' if $?.success?
75
- else
76
- log 'failed to stop'
77
- end
78
- end
79
-
80
- # Restart the servers one at the time.
81
- # Prevent downtime by making sure only one is stopped at the time.
82
- # See http://blog.carlmercier.com/2007/09/07/a-better-approach-to-restarting-a-mongrel-cluster/
83
- def restart
84
- with_each_instance do |port|
85
- stop_on_port port
86
- sleep 0.1 # Let the OS do his thang
87
- start_on_port port
88
- end
89
- end
90
-
91
- def log_file_for(port)
92
- include_port_number @log_file, port
93
- end
94
-
95
- def pid_file_for(port)
96
- include_port_number @pid_file, port
97
- end
98
-
99
- def pid_for(port)
100
- File.read(pid_file_for(port)).chomp.to_i
101
- end
102
-
103
- private
104
- # Send the command to the +thin+ script
105
- def run(cmd, options={})
106
- shell_cmd = shellify(cmd, options)
107
- trace shell_cmd
108
- `#{shell_cmd}`
109
- end
110
-
111
- # Turn into a runnable shell command
112
- def shellify(cmd, options={})
113
- shellified_options = options.inject([]) do |args, (name, value)|
114
- args << case value
115
- when NilClass
116
- when TrueClass then "--#{name}"
117
- else "--#{name.to_s.tr('_', '-')}=#{value.inspect}"
118
- end
119
- end
120
- "#{@@thin} #{cmd} #{shellified_options.compact.join(' ')}"
121
- end
122
-
123
- # Wait for the pid file to be created (exist=true) of deleted (exist=false)
124
- def wait_until_pid(exist, port)
125
- Timeout.timeout(@timeout) do
126
- sleep 0.1 until File.exist?(pid_file_for(port)) == !!exist
127
- end
128
- true
129
- rescue Timeout::Error
130
- false
131
- end
132
-
133
- def with_each_instance
134
- @size.times do |n|
135
- port = @first_port + n
136
- yield port
137
- end
138
- end
139
-
140
- # Add the port numbers in the filename
141
- # so each instance get its own file
142
- def include_port_number(path, port)
143
- raise ArgumentError, "filename '#{path}' must include an extension" unless path =~ /\./
144
- path.gsub(/\.(.+)$/) { ".#{port}.#{$1}" }
145
- end
146
- end
147
- end