Permalink
Browse files

Rack::ProcTitle - request status in $0

Updates the process title ($0) with request status information
before passing each request downstream. The process title format
is similar to the mongrel_proctitle and thin_proctitle extensions
that have been floating around for some time.
  • Loading branch information...
1 parent 77bfb4d commit b1a4195a8f4ffd7f2c357ffacaad1c93692a3aab @rtomayko rtomayko committed Dec 31, 2008
Showing with 58 additions and 0 deletions.
  1. +2 −0 README.rdoc
  2. +1 −0 lib/rack/contrib.rb
  3. +30 −0 lib/rack/proctitle.rb
  4. +25 −0 test/spec_rack_proctitle.rb
View
@@ -16,6 +16,8 @@ interface:
* Rack::PostBodyContentTypeParser - Adds support for JSON request bodies. The
Rack parameter hash is populated by deserializing the JSON data provided in
the request body when the Content-Type is application/json.
+* Rack::ProcTitle - Displays request information in process title ($0) for
+ monitoring/inspection with ps(1).
* Rack::Profiler - Uses ruby-prof to measure request time.
* Rack::Sendfile - Enables X-Sendfile support for bodies that can be served
from file.
View
@@ -13,6 +13,7 @@ def self.release
autoload :Locale, "rack/locale"
autoload :MailExceptions, "rack/mailexceptions"
autoload :PostBodyContentTypeParser, "rack/post_body_content_type_parser"
+ autoload :ProcTitle, "rack/proctitle"
autoload :Profiler, "rack/profiler"
autoload :Sendfile, "rack/sendfile"
autoload :TimeZone, "rack/time_zone"
View
@@ -0,0 +1,30 @@
+module Rack
+ # Middleware to update the process title ($0) with information about the
+ # current request. Based loosely on:
+ # - http://purefiction.net/mongrel_proctitle/
+ # - http://github.com/grempe/thin-proctitle/tree/master
+ #
+ # NOTE: This will not work properly in a multi-threaded environment.
+ class ProcTitle
+ F = ::File
+ PROGNAME = F.basename($0)
+
+ def initialize(app)
+ @app = app
+ @appname = Dir.pwd.split('/').reverse.
+ find { |name| name !~ /^(\d+|current|releases)$/ } || PROGNAME
+ @requests = 0
+ $0 = "#{PROGNAME} [#{@appname}] init ..."
+ end
+
+ def call(env)
+ host, port = env['SERVER_NAME'], env['SERVER_PORT']
+ meth, path = env['REQUEST_METHOD'], env['PATH_INFO']
+ @requests += 1
+ $0 = "#{PROGNAME} [#{@appname}/#{port}] (#{@requests}) " \
+ "#{meth} #{path}"
+
+ @app.call(env)
+ end
+ end
+end
@@ -0,0 +1,25 @@
+require 'rack/mock'
+require 'rack/proctitle'
+
+context "Rack::ProcTitle" do
+ F = ::File
+
+ progname = File.basename($0)
+ appname = F.expand_path(__FILE__).split('/')[-3]
+
+ def simple_app(body=['Hello World!'])
+ lambda { |env| [200, {'Content-Type' => 'text/plain'}, body] }
+ end
+
+ specify "should set the process title when created" do
+ Rack::ProcTitle.new(simple_app)
+ $0.should.equal "#{progname} [#{appname}] init ..."
+ end
+
+ specify "should set the process title on each request" do
+ app = Rack::ProcTitle.new(simple_app)
+ req = Rack::MockRequest.new(app)
+ 10.times { req.get('/hello') }
+ $0.should.equal "#{progname} [#{appname}/80] (10) GET /hello"
+ end
+end

6 comments on commit b1a4195

@josh
Contributor
josh commented on b1a4195 Jan 12, 2009

Cool idea, maybe there should be an `assert !env[“rack.multithread”]`

@rtomayko
Contributor

josh: ahh, good point. I’ll get something in for that. Do we have any existing idioms for marking non-thread-safe components as such? Using assert seems fine to me.

@josh
Contributor
josh commented on b1a4195 Jan 12, 2009

I came up with my own. Most web servers are multithreaded by default and should set the flag to true. However, middleware could change this flag.

See my locking middleware in Rails.
http://github.com/rails/rails/tree/master/actionpack/lib/action_controller/lock.rb

@rtomayko
Contributor

Awesome. Can I bring the mutexing middleware into rack-contrib? I need that for rack-cache, actually.

@josh
Contributor
josh commented on b1a4195 Jan 13, 2009

Sure thing!

Actually smells like rack-core, but rack-contrib is a good stepping stone.

@rtomayko
Contributor

I had the exact same thought right after I commented — definitely rack core material.

Please sign in to comment.