ap4r 0.3.5 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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