Class: Mongrel::Proctitler

Inherits:
Object
  • Object
show all
Defined in:
lib/mongrel_proctitle.rb

Overview

Mongrel process title modification.

Instance Method Summary collapse

Constructor Details

#initialize(port, prefix) ⇒ Proctitler

Initializes titler.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/mongrel_proctitle.rb', line 7

def initialize(port, prefix)
  @prefix = prefix
  @port = port
  @mutex = Mutex.new
  @titles = []
  @request_threads = []
  @queue_length = 0
  @request_count = 0
  
  @updater_thread = Thread.new do
    while true
      @mutex.synchronize do
        set_request_list_title
      end
      sleep 0.5
    end
  end
end

Instance Method Details

#portObject

Returns port used in title.



27
28
29
# File 'lib/mongrel_proctitle.rb', line 27

def port
  @port
end

#port=(new_port) ⇒ Object

Return port used in title.



32
33
34
# File 'lib/mongrel_proctitle.rb', line 32

def port=(new_port)
  @port = new_port
end

#request(&block) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/mongrel_proctitle.rb', line 41

def request(&block)
  titles, mutex = @titles, @mutex
  mutex.synchronize do
    @queue_length += 1
    titles.push(self.title)
  end
  begin
    yield
  ensure
    mutex.synchronize do
      @queue_length -= 1
      @request_count += 1
      
      @last_time = Time.now.to_f - Thread.current[:arrived_at].to_f
      @last_request_str = Thread.current[:request_str].to_s
                
      @request_threads.delete(Thread.current)
      set_request_list_title
    end
  end
end

#revisionObject

Returns revision used in title.



37
38
39
# File 'lib/mongrel_proctitle.rb', line 37

def revision
  @revision ||= get_app_revision if self.respond_to?(:get_app_revision)
end

#set_handling(request) ⇒ Object

Reports process as handling a socket.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/mongrel_proctitle.rb', line 106

def set_handling(request)
  params = request.params
  address = params['REMOTE_ADDR']
  method = params['REQUEST_METHOD']
  path = params['REQUEST_PATH']
  # path = "#{path[0, 60]}..." if path.length > 60
  # Thread.current[:request_str] = "#{address}: #{method} #{path}"
  Thread.current[:request_str] = "#{method} #{path}"
  Thread.current[:arrived_at] = Time.now.to_f
  @mutex.synchronize do
    @request_threads.push(Thread.current)
    set_request_list_title(Thread.current)
  end
end

#set_idleObject

Reports process as being idle.



94
95
96
97
98
# File 'lib/mongrel_proctitle.rb', line 94

def set_idle
  str = "idle#{' '*20}"
  str << "[last #{time_delta_abbriv(@last_time)} #{@last_request_str}]" if @last_time && @last_request_str
  self.title = str
end

#set_processing(socket) ⇒ Object

Reports process as handling a socket.



101
102
103
# File 'lib/mongrel_proctitle.rb', line 101

def set_processing(socket)
  self.title = "handling #{socket.peeraddr.last}"
end

#set_request_list_title(excluding = nil) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/mongrel_proctitle.rb', line 63

def set_request_list_title(excluding = nil)
  if @request_threads.empty?
    set_idle
  else
    if defined?(Rails)
      # find the first awake/critical thread and put it in the front
      running_thread = @request_threads.detect {|thread| thread.status == "run" && excluding != thread }
      @request_threads.unshift(@request_threads.delete(running_thread)) if running_thread
      # this isn't exact, but it works for most situations
    end
    now = Time.now.to_f
    list = @request_threads.inject([]) do |str, thread|
      str << "#{time_delta_abbriv(now - thread[:arrived_at])} #{thread[:request_str]}"
    end.join(" | ")
    self.title = "handling #{list}"
  end
end

#time_delta_abbriv(delta) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/mongrel_proctitle.rb', line 81

def time_delta_abbriv(delta)
  if delta < 60
    "%.1fs" % delta
  elsif delta < 3600
    "#{delta.to_i / 60}m#{delta.to_i % 60}s"
  elsif delta < 86400
    "#{delta.to_i / 3600}h#{(delta.to_i % 3600) / 60}m"
  else
    "#{delta.to_i / 86400}d#{(delta.to_i % 86400) / 3600}h"
  end
end

#titleObject

Returns current title



122
123
124
# File 'lib/mongrel_proctitle.rb', line 122

def title
  @title
end

#title=(title) ⇒ Object

Sets process title.



127
128
129
130
# File 'lib/mongrel_proctitle.rb', line 127

def title=(title)
  @title = title
  update_process_title
end

#update_process_titleObject

Updates the process title.



133
134
135
136
137
138
139
140
141
# File 'lib/mongrel_proctitle.rb', line 133

def update_process_title
  title = "#{@prefix} ["
  title << (@port ? "#{@port}" : "?")
  title << (revision ? "/r#{revision}" : "")
  title << "/#{@queue_length}"
  title << "/#{@request_count}"
  title << "]: #{@title}"
  $0 = title
end