ap4r 0.3.1 → 0.3.2

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.
@@ -1,10 +1,11 @@
1
1
  # Author:: Shunichi Shinohara
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  require 'active_support'
6
6
 
7
- module ReliableMsg
7
+ module ReliableMsg #:nodoc:
8
+
8
9
  # This class is too much experimental.
9
10
  # The aim: for performance monitoring, records unprocessed message count
10
11
  # in every queues at some interval.
@@ -1,5 +1,5 @@
1
1
  # Author:: Shunichi Shinohara
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  module Ap4r
@@ -1,5 +1,5 @@
1
1
  # Author:: Shunichi Shinohara
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  require 'rubygems'
@@ -1,5 +1,5 @@
1
1
  # Author:: Shunichi Shinohara
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  $:.unshift(File.join(File.dirname(__FILE__), '../../'))
@@ -1,5 +1,5 @@
1
1
  # Author:: Shunichi Shinohara
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  require 'fileutils'
@@ -8,7 +8,7 @@ require 'optparse'
8
8
  module Ap4r
9
9
  module Script
10
10
  class WorkspaceGenerator < Base
11
- AP4R_Directories = %w(config log script tmp)
11
+ AP4R_Directories = %w(config log public script tmp)
12
12
 
13
13
  def run argv, options
14
14
  OptionParser.new {|opt|
@@ -1,13 +1,16 @@
1
1
  # Author:: Shunichi Shinohara
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
+ # Sample script to use Log4R
6
+
5
7
  require 'rubygems'
6
8
  require 'log4r'
7
9
  require 'log4r/yamlconfigurator'
8
10
  # we use various outputters, so require them, otherwise config chokes
9
11
  require 'log4r/outputter/datefileoutputter'
10
12
  require 'log4r/outputter/emailoutputter'
13
+
11
14
  include Log4r
12
15
 
13
16
  cfg = YamlConfigurator
@@ -1,5 +1,5 @@
1
1
  # Author:: Kiwamu Kato
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  begin require 'rubygems'; rescue LoadError; end
@@ -25,9 +25,12 @@ module Ap4r
25
25
  # :queue_message => message, :queue_headers => options})
26
26
  #
27
27
  module StoreAndForward
28
-
29
- DRUBY_URI = "druby://#{ENV['AP4R_DRUBY_HOST']||'localhost'}:#{ENV['AP4R_DRUBY_PORT'] || \
30
- '6438'}"
28
+ # TODO: make AsyncController include this module. 2007/05/02 by shino
29
+
30
+ # TODO: constant or class variable, whick is better? 2007/05/02 by shino
31
+ DRUBY_HOST = ENV['AP4R_DRUBY_HOST'] || 'localhost'
32
+ DRUBY_PORT = ENV['AP4R_DRUBY_PORT'] || '6438'
33
+ DRUBY_URI = "druby://#{DRUBY_HOST}:#{DRUBY_PORT}"
31
34
 
32
35
  # This method needs information about stored message, such as
33
36
  # putting queue's name, message, options, as aruments.
@@ -59,6 +62,7 @@ module Ap4r
59
62
  # See the StoreMessage rdoc for more details.
60
63
  #
61
64
  def __ap4r_forward_by_stored_message_id(stored_message_id, options)
65
+ raise "not implemented"
62
66
  # TODO: Find record and make queue info , 2006/10/13 kato-k
63
67
  queue_name = nil
64
68
  queue_message = nil
@@ -68,7 +72,7 @@ module Ap4r
68
72
  alias :forward_by_stored_message_id :__ap4r_forward_by_stored_message_id
69
73
 
70
74
 
71
- # Put a message into queue.
75
+ # Puts a message into queue.
72
76
  # As queue_headers, some options are supported.
73
77
  # See the reliable-msg docuememt for more details.
74
78
  def __ap4r_queue_put(queue_name, queue_message, queue_headers)
@@ -84,7 +88,7 @@ end
84
88
  # For test
85
89
  if __FILE__ == $0
86
90
 
87
- class TestSaf
91
+ class TestSaf #:nodoc:
88
92
 
89
93
  include ::Ap4r::StoreAndForward
90
94
 
@@ -1,5 +1,5 @@
1
1
  # Author:: Kiwamu Kato
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  begin
@@ -59,13 +59,14 @@ module Ap4r
59
59
  # * :delete_mode (:physical or :logical)
60
60
  # Default delete mmode is physical.
61
61
  # If you need logical delete, for example you neeed checking message
62
- # duplication etc, Set the instance variable appropriately.
62
+ # duplication etc, set the <tt>Ap4r::AsyncController.saf_delete_mode</tt>
63
+ # <tt>:logical</tt>.
63
64
  def self.destroy_if_exists(id, options)
64
65
  result = nil
65
66
  begin
66
67
  result = StoredMessage.find(id)
67
68
  rescue ActiveRecord::RecordNotFound
68
- # There are chances that othere thread or process already forwarded.
69
+ # There are possibilities that other threads or processes have already forwarded.
69
70
  return nil
70
71
  end
71
72
  result.destroy_or_update(options)
@@ -1,5 +1,5 @@
1
- # Author:: Shunichi Shinohara
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
1
+ # Author:: Shunichi Shinohara
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  $KCODE = 'u'
@@ -71,7 +71,7 @@ Ap4r::Configuration.load_setting_files
71
71
 
72
72
  $original_main = self
73
73
 
74
- class Object
74
+ class Object #:nodoc:
75
75
  Ap4r::Configuration.services.each {|s|
76
76
  module_eval <<-EOS
77
77
  def #{s.name.to_s}
@@ -1,5 +1,5 @@
1
1
  # Author:: Shunichi Shinohara
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  module Ap4r::Util #:nodoc:
@@ -1,5 +1,5 @@
1
1
  # Author:: Kiwamu Kato
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  module Ap4r
@@ -8,7 +8,7 @@ module Ap4r
8
8
  module VERSION #:nodoc:
9
9
  MAJOR = 0
10
10
  MINOR = 3
11
- TINY = 1
11
+ TINY = 2
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY].join('.')
14
14
  end
@@ -1,5 +1,5 @@
1
1
  # Author:: Shunichi Shinohara
2
- # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
2
+ # Copyright:: Copyright (c) 2007 Future Architect Inc.
3
3
  # Licence:: MIT Licence
4
4
 
5
5
  require 'reliable-msg'
@@ -24,21 +24,31 @@ module Ap4r
24
24
 
25
25
  module Base
26
26
  Converters = {}
27
- DRUBY_URI = "druby://#{ENV['AP4R_DRUBY_HOST']||'localhost'}:#{ENV['AP4R_DRUBY_PORT'] || '6438'}"
27
+
28
+ # TODO: constant or class variable, whick is better? 2007/05/02 by shino
29
+ DRUBY_HOST = ENV['AP4R_DRUBY_HOST'] || 'localhost'
30
+ DRUBY_PORT = ENV['AP4R_DRUBY_PORT'] || '6438'
31
+ DRUBY_URI = "druby://#{DRUBY_HOST}:#{DRUBY_PORT}"
28
32
 
29
33
  @@default_dispatch_mode = :HTTP
30
- @@default_rm_options = { :delivery => :once }
34
+ @@default_rm_options = { :delivery => :once, :dispatch_mode => @@default_dispatch_mode }
31
35
  @@default_queue_prefix = "queue."
32
36
 
33
37
  mattr_accessor :default_dispatch_mode, :default_rm_options, :default_queue_prefix, :saf_delete_mode
34
38
 
35
- # Provide at-least-once QoS level.
36
- # Execute application logic and store the message for next logic to the application
37
- # database. This is a store processing. After commit to the database,
38
- # put the message into queue and update or delte a management table.
39
- # This is a forward processing.
40
- # SAF(store and forward) processing like this guarantees that any message
41
- # is never lost and keeps reasonable performance.
39
+ # Provides at-least-once QoS level.
40
+ # +block+ are tipically composed of database accesses and +async_dispatch+ calls.
41
+ # Database accesses are executed transactionallly by +active_record_class+'s transaction method.
42
+ # In the +block+, +async_dispatch+ calls invoke NOT immediate queueing but just storing messages
43
+ # to the database (assumed to be the same one as application uses).
44
+ #
45
+ # If the execution of +block+ finishes successfully, database transaction is committed and
46
+ # forward process of each stored message begins.
47
+ # Forward process composed in two parts. First puts the message into a queue, secondary update
48
+ # or delete the entry from a management table.
49
+ #
50
+ # SAF (store and forward) processing like this guarantees that any message
51
+ # is never lost and keeps reasonable performance (without two phase commit).
42
52
  #
43
53
  # Examples: Just call async_dispath method in this block.
44
54
  #
@@ -57,7 +67,7 @@ module Ap4r
57
67
  Thread.current[:stored_messages] = {}
58
68
 
59
69
  # store
60
- active_record_class ||= StoredMessage
70
+ active_record_class ||= ::Ap4r::StoredMessage
61
71
  active_record_class.transaction(*objects, &block)
62
72
 
63
73
  # forward
@@ -68,13 +78,14 @@ module Ap4r
68
78
  # Once some error occured, such as disconnect reliable-msg or server crush,
69
79
  # which is smart to keep to put a message or stop to do it?
70
80
  # In the case of being many async messages, the former strategy is not so good.
81
+ #
82
+ # TODO: add delayed forward mode 2007/05/02 by shino
71
83
  Thread.current[:stored_messages].each {|k,v|
72
84
  __queue_put(v[:queue_name], v[:queue_message], v[:queue_headers])
73
85
  forwarded_messages[k] = v
74
86
  }
75
87
  rescue Exception => err
76
- # Don't raise any Exception. Response to user already completed.
77
- # nop
88
+ # Don't raise any Exception. Application logic has already completed and messages are saved.
78
89
  logger.warn("Failed to put a message into queue: #{err}")
79
90
  end
80
91
 
@@ -86,8 +97,7 @@ module Ap4r
86
97
  }
87
98
  end
88
99
  rescue Exception => err
89
- # Don't raise any Exception. Response to user already completed.
90
- # nop
100
+ # Don't raise any Exception. Application logic has already completed and messages are saved.
91
101
  logger.warn("Failed to put a message into queue: #{err}")
92
102
  end
93
103
 
@@ -115,29 +125,28 @@ module Ap4r
115
125
  # Object of argumemts (async_params, options and rm_options) will not be modified.
116
126
  # Implementors (of this class and converters) should not modify them.
117
127
  #
118
- def async_dispatch(async_params = nil, options = {}, rm_options = nil)
128
+ def async_dispatch(url_options = {}, async_params = nil, rm_options = nil)
129
+ # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino
119
130
  if logger.debug?
131
+ logger.debug("url_options: ")
132
+ logger.debug(url_options.inspect)
120
133
  logger.debug("async_params: ")
121
134
  logger.debug(async_params.inspect)
122
- logger.debug("options: ")
123
- logger.debug(options.inspect)
124
- logger.debug("rm_options")
135
+ logger.debug("rm_options: ")
125
136
  logger.debug(rm_options.inspect)
126
137
  end
127
138
 
128
139
  # TODO: clone it, 2006/10/16 shino
129
- options ||= {}
130
- options[:controller] ||= controller_path.gsub("/", ".")
140
+ url_options ||= {}
141
+ url_options[:controller] ||= self.controller_path.gsub("/", ".")
131
142
  rm_options = @@default_rm_options.merge(rm_options || {})
132
- # TODO: put into :dispatch_mode to @@default_rm_options
133
- rm_options[:dispatch_mode] ||= @@default_dispatch_mode
134
143
 
135
144
  # Only async_params is not cloned. options and rm_options are cloned before now.
136
145
  # This is a current contract between this class and converter classes.
137
- converter = Converters[rm_options[:dispatch_mode]].new(self, async_params, options, rm_options)
146
+ converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self)
138
147
  logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"}
139
148
 
140
- queue_name = __get_queue_name(options, rm_options)
149
+ queue_name = __get_queue_name(url_options, rm_options)
141
150
  queue_message = converter.make_params
142
151
  queue_headers = converter.make_rm_options
143
152
 
@@ -159,6 +168,7 @@ module Ap4r
159
168
 
160
169
  private
161
170
  def __queue_put(queue_name, queue_message, queue_headers)
171
+ # TODO: can use a Queue instance repeatedly? 2007/05/02 by shino
162
172
  q = ReliableMsg::Queue.new(queue_name, :drb_uri => DRUBY_URI)
163
173
  q.put(queue_message, queue_headers)
164
174
  end
@@ -171,15 +181,14 @@ module Ap4r
171
181
 
172
182
  end
173
183
 
174
- #--
175
- # TODO: pluralize it, 2006/10/16 shino
176
- module Converter #:nodoc:
184
+ module Converters #:nodoc:
177
185
 
178
186
  # A base class for converter classes.
179
187
  # Responsibilities of subclasses are as folows
180
188
  # * by +make_params+, convert async_params to appropriate object
181
189
  # * by +make_rm_options+, make appropriate +Hash+ passed by <tt>ReliableMsg::Queue#put</tt>
182
190
  class Base
191
+
183
192
  # Difine a constant +DISPATCH_MODE+ to value 'mode_symbol' and
184
193
  # add self to a Converters list.
185
194
  def self.dispatch_mode(mode_symbol)
@@ -187,31 +196,33 @@ module Ap4r
187
196
  ::Ap4r::AsyncController::Base::Converters[mode_symbol] = self
188
197
  end
189
198
 
190
- def initialize(controller, async_params, options, rm_options)
191
- @controller = controller
199
+ def initialize(url_options, async_params, rm_options, url_for_handler)
200
+ @url_options = url_options
192
201
  @async_params = async_params
193
- @options = options
194
202
  @rm_options = rm_options
195
- end
196
-
197
- # helper method for <tt>ActionController#url_for</tt>
198
- def url_for(url_for_options, *parameter_for_method_reference)
199
- @controller.url_for(url_for_options, *parameter_for_method_reference)
203
+ @url_for_handler = url_for_handler
200
204
  end
201
205
 
202
206
  # Returns a object which passed to <tt>ReliableMsg::Queue.put(message, headers)</tt>'s
203
207
  # first argument +message+.
204
208
  # Should be implemented by subclasses.
205
209
  def make_params
206
- raise 'must be implemented'
210
+ raise 'must be implemented in subclasses'
207
211
  end
208
212
 
209
213
  # Returns a object which passed to <tt>ReliableMsg::Queue.put(message, headers)</tt>'s
210
214
  # second argument +headers+.
211
215
  # Should be implemented by subclasses.
212
216
  def make_rm_options
213
- raise 'must be implemented'
217
+ raise 'must be implemented in subclasses'
214
218
  end
219
+
220
+ private
221
+ # helper method for <tt>ActionController#url_for</tt>
222
+ def url_for(url_for_options, *parameter_for_method_reference)
223
+ @url_for_handler.url_for(url_for_options, *parameter_for_method_reference)
224
+ end
225
+
215
226
  end
216
227
 
217
228
  class Http < Base
@@ -222,7 +233,7 @@ module Ap4r
222
233
  end
223
234
 
224
235
  def make_rm_options
225
- @rm_options[:target_url] ||= url_for(@options)
236
+ @rm_options[:target_url] ||= url_for(@url_options)
226
237
  @rm_options[:target_method] ||= 'POST'
227
238
  #TODO: make option key to specify HTTP headers, 2006/10/16 shino
228
239
  @rm_options
@@ -243,12 +254,12 @@ module Ap4r
243
254
  end
244
255
 
245
256
  def action_api_name
246
- action_method_name = @options[:action]
257
+ action_method_name = @url_options[:action]
247
258
  action_method_name.camelcase
248
259
  end
249
260
 
250
261
  def options_without_action
251
- new_opts = @options.dup
262
+ new_opts = @url_options.dup
252
263
  new_opts[:action] = nil
253
264
  new_opts
254
265
  end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'ap4r'
3
+
4
+ load 'ap4r/mongrel_ap4r.rb'
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: ap4r
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.3.1
7
- date: 2007-04-24 00:00:00 +09:00
6
+ version: 0.3.2
7
+ date: 2007-06-06 00:00:00 +09:00
8
8
  summary: Asynchronous Processing for Ruby.
9
9
  require_paths:
10
10
  - lib
@@ -36,12 +36,11 @@ files:
36
36
  - doc
37
37
  - lib
38
38
  - MIT-LICENSE
39
- - pkg
40
39
  - rails_plugin
41
40
  - Rakefile
42
41
  - README
43
42
  - script
44
- - temp
43
+ - spec
45
44
  - bin/ap4r_setup
46
45
  - config/ap4r_settings.rb
47
46
  - config/log4r.yaml
@@ -49,18 +48,20 @@ files:
49
48
  - config/queues_disk.cfg
50
49
  - config/queues_mysql.cfg
51
50
  - rails_plugin/ap4r
52
- - rails_plugin/ap4r/init.rb
53
51
  - rails_plugin/ap4r/lib
54
52
  - rails_plugin/ap4r/lib/async_controller.rb
55
53
  - script/irm
56
54
  - script/loop.cmd
57
55
  - script/loop.rb
58
- - script/mongrel_ap4r.rb
56
+ - script/mongrel_ap4r
59
57
  - script/start
60
58
  - script/stop
61
59
  - lib/ap4r
60
+ - lib/ap4r/carrier.rb
61
+ - lib/ap4r/dispatcher.rb
62
62
  - lib/ap4r/message_store_ext.rb
63
63
  - lib/ap4r/mongrel.rb
64
+ - lib/ap4r/mongrel_ap4r.rb
64
65
  - lib/ap4r/multi_queue.rb
65
66
  - lib/ap4r/queue_manager_ext.rb
66
67
  - lib/ap4r/queue_manager_ext_debug.rb
@@ -75,10 +76,8 @@ files:
75
76
  - lib/ap4r/stored_message.rb
76
77
  - lib/ap4r/util
77
78
  - lib/ap4r/util/irm.rb
78
- - lib/ap4r/util/loc.rb
79
79
  - lib/ap4r/util/queue_client.rb
80
80
  - lib/ap4r/version.rb
81
- - lib/ap4r/xxx_create_table_for_saf.rb
82
81
  - lib/ap4r.rb
83
82
  test_files: []
84
83
 
@@ -108,3 +107,30 @@ dependencies:
108
107
  - !ruby/object:Gem::Version
109
108
  version: 1.1.0
110
109
  version:
110
+ - !ruby/object:Gem::Dependency
111
+ name: rake
112
+ version_requirement:
113
+ version_requirements: !ruby/object:Gem::Version::Requirement
114
+ requirements:
115
+ - - ">"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.0.0
118
+ version:
119
+ - !ruby/object:Gem::Dependency
120
+ name: activesupport
121
+ version_requirement:
122
+ version_requirements: !ruby/object:Gem::Version::Requirement
123
+ requirements:
124
+ - - ">"
125
+ - !ruby/object:Gem::Version
126
+ version: 0.0.0
127
+ version:
128
+ - !ruby/object:Gem::Dependency
129
+ name: mongrel
130
+ version_requirement:
131
+ version_requirements: !ruby/object:Gem::Version::Requirement
132
+ requirements:
133
+ - - ">"
134
+ - !ruby/object:Gem::Version
135
+ version: 0.0.0
136
+ version: