ap4r 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: