ap4r 0.3.5 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,8 +1,14 @@
1
1
  == 0.3.x
2
2
 
3
+ === 0.3.6 (February 6, 2008)
4
+ * Added: configuration to set HTTP timeout.
5
+ Based on a patch from Artem Vasiliev <abublic at gmail.com>
6
+ * Added: provisional support Rails2.0.
7
+ * Changed: the location of message_builder.rb from rails plugin to ap4r core (ap4r/lib directory).
8
+ * Fixed: bug (tracker #17206) that uninitialized constant error occurs when :active_record_store is used as session store.
9
+
3
10
  === 0.3.5 (November 29, 2007)
4
- * Fixed: bug that SAF transaction is NOT guaranteed when some models are created/updated
5
- before using of ap4r.async_to API in ap4r.transaction block.
11
+ * Fixed: bug that SAF transaction is NOT guaranteed when some models are created/updated before using of ap4r.async_to API in ap4r.transaction block.
6
12
 
7
13
  === 0.3.4 (October 31, 2007)
8
14
  * Added: Support ActiveRecord as reliable RDBMS persistence.
data/Manifest.txt CHANGED
@@ -15,6 +15,7 @@ lib/ap4r.rb
15
15
  lib/ap4r/carrier.rb
16
16
  lib/ap4r/db/migrate/001_reliable_msg_queue_and_topic.rb
17
17
  lib/ap4r/dispatcher.rb
18
+ lib/ap4r/message_builder.rb
18
19
  lib/ap4r/message_store_ext.rb
19
20
  lib/ap4r/mongrel.rb
20
21
  lib/ap4r/mongrel_ap4r.rb
@@ -43,11 +44,13 @@ rails_plugin/ap4r/lib/ap4r/queue_put_stub.rb
43
44
  rails_plugin/ap4r/lib/ap4r/service_handler.rb
44
45
  rails_plugin/ap4r/lib/ap4r_client.rb
45
46
  rails_plugin/ap4r/lib/async_helper.rb
46
- rails_plugin/ap4r/lib/message_builder.rb
47
47
  rails_plugin/ap4r/tasks/ap4r.rake
48
48
  script/irm
49
49
  script/mongrel_ap4r
50
50
  script/start
51
51
  script/stop
52
52
  spec/local/dispatcher_base_spec.rb
53
+ spec/local/message_builder_spec.rb
54
+ spec/local/send_message_handler_spec.rb
55
+ spec/local/subscribe_message_handler_spec.rb
53
56
  spec/spec_helper.rb
data/Rakefile CHANGED
@@ -1,50 +1,54 @@
1
1
  require 'rubygems'
2
- require 'hoe'
3
2
  require 'erb'
3
+ require 'find'
4
4
  require 'active_record'
5
5
  require File.join(File.dirname(__FILE__), 'lib/ap4r', 'version')
6
6
 
7
- namespace :hoe do
8
- hoe = Hoe.new('ap4r', Ap4r::VERSION::STRING) do |p|
9
- p.author = ["Shunichi Shinohara", "Kiwamu Kato"]
10
- p.changes = p.paragraphs_of('History.txt', 1..2).join("\n\n")
11
- #p.clean_globs =
12
- p.description = <<-EOF
7
+ begin
8
+ namespace :hoe do
9
+ require 'hoe'
10
+
11
+ hoe = Hoe.new('ap4r', Ap4r::VERSION::STRING) do |p|
12
+ p.author = ["Shunichi Shinohara", "Kiwamu Kato"]
13
+ p.changes = p.paragraphs_of('History.txt', 1..2).join("\n\n")
14
+ #p.clean_globs =
15
+ p.description = <<-EOF
13
16
  Asynchronous Processing for Ruby.
14
17
  EOF
15
- p.email = %q{shinohara.shunichi@future.co.jp, kato.kiwamu@future.co.jp}
16
-
17
- p.extra_deps << ['reliable-msg', '=1.1.0']
18
- p.extra_deps << ['activesupport']
19
- p.extra_deps << ['mongrel']
20
- p.extra_deps << ['rake']
21
- p.extra_deps << ['hoe']
22
-
23
- p.name = 'ap4r'
24
- p.need_tar = false
25
- p.need_zip = false
26
- p.rdoc_pattern = /^(lib|bin|ext|rails_plugin)|txt$/
27
-
28
- #p.remote_rdoc_dir =
29
- #p.rsync =
30
- p.rubyforge_name = 'ap4r'
31
- #p.spec_extra =
32
- p.summary = 'Asynchronous Processing for Ruby.'
33
- p.test_globs = 'spec/**/*_spec.rb'
34
- p.url = 'http://ap4r.rubyforge.org/wiki/wiki.pl?HomePage'
35
- p.version = Ap4r::VERSION::STRING
36
- end
37
- hoe.spec.dependencies.delete_if {|dep| dep.name == "hoe"}
18
+ p.email = %q{shinohara.shunichi@future.co.jp, kato.kiwamu@future.co.jp}
19
+
20
+ p.extra_deps << ['reliable-msg', '=1.1.0']
21
+ p.extra_deps << ['activesupport']
22
+ p.extra_deps << ['mongrel']
23
+ p.extra_deps << ['rake']
24
+ p.extra_deps << ['hoe']
25
+
26
+ p.name = 'ap4r'
27
+ p.need_tar = false
28
+ p.need_zip = false
29
+ p.rdoc_pattern = /^(lib|bin|ext|rails_plugin)|txt$/
30
+
31
+ #p.remote_rdoc_dir =
32
+ #p.rsync =
33
+ p.rubyforge_name = 'ap4r'
34
+ #p.spec_extra =
35
+ p.summary = 'Asynchronous Processing for Ruby.'
36
+ p.test_globs = 'spec/**/*_spec.rb'
37
+ p.url = 'http://ap4r.rubyforge.org/wiki/wiki.pl?HomePage'
38
+ p.version = Ap4r::VERSION::STRING
39
+ end
40
+ hoe.spec.dependencies.delete_if {|dep| dep.name == "hoe"}
38
41
 
42
+ end
43
+ rescue
39
44
  end
40
- task :pkg => "release:copy_plugin"
41
45
 
42
46
  # AP4R release tasks --------------------------------------------------------
43
47
 
44
48
  HelloWorld = '../samples/HelloWorld'
45
49
 
46
50
  namespace :release do
47
- desc "copy rails plugin from sample before gem build"
51
+ desc "copy rails plugin from sample before gem build"
48
52
  task :copy_plugin do
49
53
  # TODO: Should use file task ? 2007/09/27 by shino
50
54
  FileUtils.rm_rf('./rails_plugin/ap4r')
@@ -61,8 +65,10 @@ namespace :release do
61
65
  path_list = []
62
66
  Find.find('.') do |path|
63
67
  next unless File.file?(path)
68
+ next if path =~ /^\.\/coverage\//
64
69
  next if path =~ /^\.\/doc\//
65
- next if path =~ /\.svn|tmp$|CVS|\~$/
70
+ next if path =~ /^\.\/log\//
71
+ next if path =~ /\.svn|tmp$|CVS|\.msg$|\.idx$|\.state$|\#$|\~$/
66
72
  path_list << path
67
73
  end
68
74
 
@@ -79,7 +85,7 @@ namespace :release do
79
85
  task :sample do
80
86
  FileUtils.mkdir_p('./pkg/samples')
81
87
  FileUtils.rm_rf('./pkg/samples/HelloWorld')
82
-
88
+
83
89
  FileUtils.cp_r(HelloWorld, './pkg/samples/')
84
90
  Find.find('./pkg/samples') do |path|
85
91
  next unless File.file? path
@@ -89,12 +95,13 @@ namespace :release do
89
95
  Dir.chdir('./pkg/samples/HelloWorld')
90
96
  `rake db:migrate`
91
97
  Dir.chdir('../../')
92
-
98
+
93
99
  `tar czf HelloWorld-#{Ap4r::VERSION::STRING}.tar.gz ./samples/HelloWorld/`
94
100
  Dir.chdir('../')
95
101
  end
96
102
  end
97
103
 
104
+ task :pkg => "release:copy_plugin"
98
105
 
99
106
  # Spec tasks ----------------------------------------------------------------
100
107
  require 'spec/rake/spectask'
@@ -111,10 +118,15 @@ namespace :spec do
111
118
  Spec::Rake::SpecTask.new(flavor) do |t|
112
119
  t.spec_files = FileList["spec/#{flavor}/**/*.rb"]
113
120
  t.rcov = true
121
+ build_artifacts = ENV['CC_BUILD_ARTIFACTS']
122
+ t.rcov_dir = build_artifacts.nil? ? "coverage" : "#{build_artifacts}"
114
123
  excludes = %w(^spec\/)
115
124
  if ENV['GEM_HOME']
116
125
  excludes << Regexp.escape(ENV['GEM_HOME'])
117
126
  end
127
+ if ENV['RUBY_HOME']
128
+ excludes << Regexp.escape(ENV['RUBY_HOME'])
129
+ end
118
130
  t.rcov_opts = ["--exclude" , excludes.join(","),
119
131
  "--text-summary"]
120
132
  end
@@ -140,7 +152,7 @@ task :stats => "release:copy_plugin" do
140
152
  end
141
153
 
142
154
  namespace :qdb do
143
- desc "Make queue and topic tables through scripts in lib/ap4r/db/migrate."
155
+ desc "Make queue and topic tables through scripts in lib/ap4r/db/migrate."
144
156
  task :migrate do
145
157
 
146
158
  # Todo: configurable file name, 2007/10/01 kiwamu
@@ -159,3 +171,43 @@ namespace :qdb do
159
171
  end
160
172
  end
161
173
 
174
+ todos_dirs = %w(lib rails_plugin spec)
175
+
176
+ desc "List TODO comments in #{todos_dirs.join(", ")} directories"
177
+ task :todos => todos_dirs.map{ |dir| "todos:#{dir}" }
178
+
179
+ namespace :todos do
180
+ todos_dirs.each do |dir|
181
+ desc "List TODO comments in #{dir} directory"
182
+ task dir => "release:copy_plugin" do
183
+ print_todos(dir)
184
+ end
185
+ end
186
+
187
+ def print_todos(dir)
188
+ FileList.new("#{dir}/**/*.*").each do |file|
189
+ next unless FileTest.file?(file)
190
+ next if (results = todos(file)).empty?
191
+
192
+ puts file
193
+ results.each{ |r|
194
+ puts "L.#{"%4d" % r[:line]}: #{r[:msg]} -- #{r[:date]} by #{r[:by]}"
195
+ }
196
+ puts
197
+ end
198
+ end
199
+
200
+ def todos(file)
201
+ pattern = /TODO\s*:?\s*(.*)\s+(\d{4}\/\d{2}\/\d{2})\s*,?(?:by)?\s*(\S+)/i
202
+
203
+ results = []
204
+ File.open(file, "r") do |f|
205
+ f.each_line do |line|
206
+ next unless pattern.match(line)
207
+ results << {:line => f.lineno, :by => $3, :date => $2, :msg => $1.strip}
208
+ end
209
+ end
210
+ results
211
+ end
212
+
213
+ end
data/lib/ap4r/carrier.rb CHANGED
@@ -2,11 +2,12 @@
2
2
  # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
+ begin require 'rubygems'; rescue LoadError; end
6
+
5
7
  require 'yaml'
6
8
  require 'thread'
7
9
  require 'pp'
8
10
  require 'active_support'
9
-
10
11
  require 'reliable-msg'
11
12
 
12
13
  module Ap4r
@@ -80,7 +81,7 @@ module Ap4r
80
81
  # local_queue = ReliableMsg::Queue.new queue_name
81
82
  # local_queue.put m.object
82
83
  # }.join
83
-
84
+
84
85
  #version 2: store tx and set nil, and resotre tx after putting a message
85
86
  begin
86
87
  tx = Thread.current[ReliableMsg::Client::THREAD_CURRENT_TX]
@@ -94,7 +94,7 @@ module Ap4r
94
94
  # If no class for +dispatch_mode+, raises an exception.
95
95
  def get_dispather_instance(dispatch_mode, message, conf_per_targets)
96
96
  klass = @@subclasses[dispatch_mode]
97
- raise "undefined dispatch mode #{m.headers[:mode]}" unless klass
97
+ raise "undefined dispatch mode #{message.headers[:mode]}" unless klass
98
98
  klass.new(message, conf_per_targets)
99
99
  end
100
100
 
@@ -233,6 +233,12 @@ module Ap4r
233
233
  headers = make_header
234
234
 
235
235
  Net::HTTP.start(uri.host, uri.port) do |http|
236
+ # TODO: global configuration over dispatchers for each protocol should be considered, 2008/02/06 by kiwamu
237
+ # TODO: http open timeout should be considered, 2008/02/06 by kiwamu
238
+ if @conf['http'] && @conf['http']['timeout']
239
+ http.read_timeout = @conf['http']['timeout']
240
+ logger.info "set HTTP read timeout to #{http.read_timeout}s"
241
+ end
236
242
  @response, = http.post(uri.path, @message.object, headers)
237
243
  end
238
244
  end
@@ -330,7 +336,7 @@ module Ap4r
330
336
  #
331
337
  class Druby < Base
332
338
  dispatch_mode :druby
333
-
339
+
334
340
  def invoke
335
341
  object = DRbObject.new_with_uri(@message[:target_url])
336
342
  object.method_missing(@message[:target_method].to_sym, @message.object)
@@ -3,6 +3,7 @@
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  require 'active_record'
6
+ require 'active_support'
6
7
 
7
8
  module Ap4r #:nodoc:
8
9
 
@@ -81,7 +82,7 @@ module Ap4r #:nodoc:
81
82
  when :json
82
83
  set_content_type("application/json")
83
84
  when :yaml
84
- set_content_type("text/plain text/yaml")
85
+ set_content_type("text/yaml")
85
86
  else
86
87
  set_content_type("application/x-www-form-urlencoded")
87
88
  end
@@ -124,7 +125,7 @@ module Ap4r #:nodoc:
124
125
  when :text
125
126
  return @message_body.to_s
126
127
  when :xml
127
- return @message_body.to_xml @to_xml_options
128
+ return @message_body.to_xml(@to_xml_options)
128
129
  when :json
129
130
  return @message_body.to_json
130
131
  when :yaml
@@ -23,14 +23,14 @@ module ReliableMsg #:nodoc:
23
23
  queue == mq
24
24
  end
25
25
  }
26
- }.map{|queue, messages|
26
+ }.map{|queue, messages|
27
27
  [queue, messages[0][:created]]
28
28
  }.min {|q1, q2|
29
29
  q1[1] <=> q2[1]
30
30
  }
31
31
  queue_and_created ? queue_and_created[0] : nil
32
32
  end
33
-
33
+
34
34
  # Returns a message store from the specified configuration (previously
35
35
  # created with configure).
36
36
  #
@@ -60,7 +60,7 @@ module ReliableMsg #:nodoc:
60
60
  rescue LoadError
61
61
  require 'postgres-pr/connection'
62
62
  end
63
-
63
+
64
64
  require 'base64'
65
65
 
66
66
  class PostgreSQL < Base #:nodoc:
@@ -206,10 +206,10 @@ module ReliableMsg #:nodoc:
206
206
  end
207
207
 
208
208
  def connection
209
- Thread.current[THREAD_CURRENT_PGSQL] ||=
209
+ Thread.current[THREAD_CURRENT_PGSQL] ||=
210
210
  # PGconn is overriding in this file, so is defined regardless of 'postgres' LoadError.
211
211
  if Object.const_defined? :PGError
212
- ::PGconn.connect @config[:host], @config[:port], @config[:options], @config[:tty], @config[:database], @config[:username], @config[:password]
212
+ ::PGconn.connect @config[:host], @config[:port], @config[:options], @config[:tty], @config[:database], @config[:username], @config[:password]
213
213
  elsif Object.const_defined? :PostgresPR
214
214
  ::PostgresPR::Connection.new @config[:database], @config[:username], @config[:password], @config[:uri]
215
215
  end
@@ -217,16 +217,16 @@ module ReliableMsg #:nodoc:
217
217
  end
218
218
 
219
219
  end
220
-
220
+
221
221
  rescue LoadError
222
222
  # do nothing
223
223
  end
224
224
 
225
-
225
+
226
226
  begin
227
227
  # ActiveRecord
228
228
  # Make sure we have a ActiveRecord library before creating this class,
229
- # worst case we end up with a disk-based message store.
229
+ # worst case we end up with a disk-based message store.
230
230
  begin
231
231
  require 'active_record'
232
232
  require 'ap4r/reliable_msg_queue'
@@ -274,7 +274,7 @@ module ReliableMsg #:nodoc:
274
274
 
275
275
 
276
276
  def configuration
277
- config = { "type"=>TYPE, "adapter"=>@config[:adapter], "host"=>@config[:host],
277
+ config = { "type"=>TYPE, "adapter"=>@config[:adapter], "host"=>@config[:host],
278
278
  "username"=>@config[:username], "password"=>@config[:password], "database"=>@config[:database] }
279
279
  config["port"] = @config[:port] if @config[:port]
280
280
  config["socket"] = @config[:socket] if @config[:socket]
@@ -335,7 +335,7 @@ module ReliableMsg #:nodoc:
335
335
  rescue Exception=>error
336
336
  raise error
337
337
  end
338
- super
338
+ super
339
339
 
340
340
  end
341
341
 
@@ -356,7 +356,7 @@ module ReliableMsg #:nodoc:
356
356
  end
357
357
  queue << headers unless added
358
358
  end
359
-
359
+
360
360
  ::Ap4r::ReliableMsgTopic.find(:all).each do |message|
361
361
  @topocs[message[:topic]] = Marshal::load(message[:headers])
362
362
  end
@@ -391,8 +391,8 @@ module ReliableMsg #:nodoc:
391
391
  rescue LoadError
392
392
  # do nothing
393
393
  end
394
-
395
-
394
+
395
+
396
396
  class Memory < Base #:nodoc:
397
397
 
398
398
  TYPE = self.name.split('::').last.downcase
@@ -443,7 +443,7 @@ module ReliableMsg #:nodoc:
443
443
  @mutex.synchronize do
444
444
  @memory_map[insert[:id]] = insert[:message]
445
445
  end
446
- end
446
+ end
447
447
  super
448
448
  @mutex.synchronize do
449
449
  deletes.each do |delete|
@@ -476,7 +476,7 @@ if Object.const_defined? :PGError
476
476
  maybe_result.clear
477
477
  end
478
478
  end
479
-
479
+
480
480
  def quote str
481
481
  # do nothing
482
482
  str
@@ -510,15 +510,15 @@ if Object.const_defined? :PostgresPR
510
510
  # do nothing
511
511
  str
512
512
  end
513
-
514
- end
513
+
514
+ end
515
515
  end
516
516
  end
517
517
 
518
- if ReliableMsg::MessageStore::Base.use_mysql_extention
518
+ if Object.const_defined?(:Mysql) && ReliableMsg::MessageStore::Base.use_mysql_extention
519
519
  class Mysql #:nodoc:
520
520
  alias original_query query
521
-
521
+
522
522
  # In Ruby/MySQL, +query+ method does NOT care about a given block.
523
523
  # To make it behave the same as MySQL/Ruby, this method adds iteration
524
524
  # over query results.
data/lib/ap4r/mongrel.rb CHANGED
@@ -55,7 +55,7 @@ module Ap4r
55
55
 
56
56
  def initialize(options)
57
57
  # TODO: needs various modes for easy operations 2007/05/02 by shino
58
- # e.g. not to initialize message store, not to start dispatchers, etc.
58
+ # e.g. not to initialize message store, not to start dispatchers, etc.
59
59
 
60
60
  # TODO what is "false" here? 2007/04/13 by shinohara
61
61
  @files = ::Mongrel::DirHandler.new(options[:docroot], false)
@@ -100,5 +100,196 @@ module Ap4r
100
100
 
101
101
  end
102
102
 
103
+ # This class is an experimental implementation of RESTified message API.
104
+ # Send to queue:
105
+ # using HTTP POST
106
+ # a message is sent as HTTP body which format is depending on MIME type
107
+ # (now supported only text/plain)
108
+ #
109
+ # options are sent as HTTP header which header name is "X-AP4R"
110
+ # url consists of prefix ("/queues") and queue name
111
+ #
112
+ #
113
+ # === Request example ===
114
+ # POST /queues/queue.test HTTP/1.1
115
+ # Content-Type: text/plain
116
+ # X-AP4R: dispatch_mode=HTTP, target_method=POST, target_url=http://localhost:3000/async_shop/execute_via_http/
117
+ #
118
+ # hoge
119
+ #
120
+ #
121
+ # === Response example ===
122
+ # HTTP/1.1 200 Ok
123
+ # Date: The, 11 Dec 2007 17:17:11 GMT
124
+ #
125
+ # 7bb181f0-7ee0-012a-300a-001560abd426
126
+ #
127
+ class Ap4rSendMessageHandler < ::Mongrel::HttpHandler
128
+
129
+ def initialize(options)
130
+ @tick = Time.now
131
+ @queues = {}
132
+ end
133
+
134
+ def process(request, response)
135
+ if response.socket.closed?
136
+ return
137
+ end
138
+
139
+ queue_name = request.params[::Mongrel::Const::PATH_INFO][1..-1]
140
+ header = make_header(request.params["HTTP_X_AP4R"]) # Todo: assign as constant 2007/11/27 by kiwamu
141
+
142
+ if "POST".include? request.params[::Mongrel::Const::REQUEST_METHOD]
143
+ begin
144
+ q = if @queues.key? queue_name
145
+ @queues[queue_name]
146
+ else
147
+ @queues[queue_name] = ::ReliableMsg::Queue.new(queue_name)
148
+ end
149
+ mid = q.put(request.body.string, header)
150
+
151
+ response.start(200) do |head, out|
152
+ head['Content-Type'] = 'text/plain'
153
+ out.write mid
154
+ end
155
+ rescue Exception
156
+ response.start(500) do |head, out|
157
+ head['Content-Type'] = 'text/plain'
158
+ out.write "Failed to send message. #{request.body.string}"
159
+ end
160
+ end
161
+ else
162
+ raise "HTTP method is not POST..." # Todo
163
+ end
164
+ end
165
+
166
+ def make_header(x_ap4r_header)
167
+ header = {}
168
+ if x_ap4r_header
169
+ x_ap4r_header.split(',').map do |e|
170
+ key, value = e.strip.split('=')
171
+ if %w(dispatch_mode target_method delivery).include?(key)
172
+ header[key.to_sym] = value.to_sym
173
+ else
174
+ header[key.to_sym] = value
175
+ end
176
+ end
177
+ end
178
+ header
179
+ end
180
+
181
+ def log_threads_waiting_for(event)
182
+ if Time.now - @tick > 10
183
+ @tick = Time.now
184
+ end
185
+ end
186
+
187
+ # Does the internal reload for Rails. It might work for most cases, but
188
+ # sometimes you get exceptions. In that case just do a real restart.
189
+ def reload!
190
+ begin
191
+ #TODO not implemented 2007/04/09 by shino
192
+ raise "not yet implemented!"
193
+ end
194
+ end
195
+
196
+ end
197
+
198
+ # This class is an experimental implementation of RESTified message API.
199
+ # Subscribe to queue:
200
+ # using HTTP POST
201
+ # a message is subscribed as HTTP body
202
+ #
203
+ # options are sent as HTTP header which header name is "X-AP4R"
204
+ # (now not supported)
205
+ #
206
+ # url consists of prefix ("/subscribes") and queue name
207
+ #
208
+ # response body is now return value of ReliableMsg#inspct
209
+ # In the future, it will be possible to assign the format by the request header X-AP4R
210
+ #
211
+ #
212
+ # === Rrequest example ===
213
+ # POST /subscribes/queue.test HTTP/1.1
214
+ #
215
+ #
216
+ # === Response example ===
217
+ # HTTP/1.1 200 Ok
218
+ # Content-Type: text/plain
219
+ # Date: The, 11 Dec 2007 17:17:11 GMT
220
+ #
221
+ # #<ReliableMsg::Message:0x320ec90 @headers={:priority=>0, :created=>1197628231, :expires=>nil, :delivery=>:best_effort, :id=>\"856016b0-8c5d-012a-79f3-0016cb9ad524\", :max_deliveries=>5}, @object=\"hoge\", @id=\"856016b0-8c5d-012a-79f3-0016cb9ad524\">
222
+ #
223
+ class Ap4rSubscribeMessageHandler < ::Mongrel::HttpHandler
224
+
225
+ def initialize(options)
226
+ @tick = Time.now
227
+ @queues = {}
228
+ end
229
+
230
+ def process(request, response)
231
+ if response.socket.closed?
232
+ return
233
+ end
234
+
235
+ queue_name = request.params[::Mongrel::Const::PATH_INFO][1..-1]
236
+ # header = make_header(request.params["HTTP_X_AP4R"]) # Todo: assign as constant 2007/11/27 by kiwamu
237
+
238
+ if "POST".include? request.params[::Mongrel::Const::REQUEST_METHOD]
239
+ begin
240
+ q = if @queues.key? queue_name
241
+ @queues[queue_name]
242
+ else
243
+ @queues[queue_name] = ::ReliableMsg::Queue.new(queue_name)
244
+ end
245
+ mes = q.get
246
+
247
+ response.start(200) do |head, out|
248
+ head['Content-Type'] = 'text/plain'
249
+ out.write mes.inspect
250
+ end
251
+ rescue
252
+ response.start(500) do |head, out|
253
+ head['Content-Type'] = 'text/plain'
254
+ out.write "Failed to get message for #{queue_name}"
255
+ end
256
+ end
257
+ else
258
+ raise "HTTP method is not POST..."
259
+ end
260
+ end
261
+
262
+ def make_header(x_ap4r_header)
263
+ header = {}
264
+ if x_ap4r_header
265
+ x_ap4r_header.split(',').map do |e|
266
+ key, value = e.strip.split('=')
267
+ if %w(dispatch_mode target_method delivery).include?(key)
268
+ header[key.to_sym] = value.to_sym
269
+ else
270
+ header[key.to_sym] = value
271
+ end
272
+ end
273
+ end
274
+ header
275
+ end
276
+
277
+ def log_threads_waiting_for(event)
278
+ if Time.now - @tick > 10
279
+ @tick = Time.now
280
+ end
281
+ end
282
+
283
+ # Does the internal reload for Rails. It might work for most cases, but
284
+ # sometimes you get exceptions. In that case just do a real restart.
285
+ def reload!
286
+ begin
287
+ #TODO not implemented 2007/04/09 by shino
288
+ raise "not yet implemented!"
289
+ end
290
+ end
291
+
292
+ end
293
+
103
294
  end
104
295
  end