From shinohara.shunichi at future.co.jp Thu May 10 00:17:53 2007
From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp)
Date: Thu, 10 May 2007 13:17:53 +0900
Subject: [ap4r-devel] test
Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDA0@045MAIL.future.co.jp>
test again
---------------------------------
SHINOHARA, Shun'ichi
Future Architect, Inc.
1-2-2 Osaki Shinagawa-Ku
Tokyo, JAPAN (ZIP 141-0032)
070-6991-0765 (cell phone)
shinohara.shunichi at future.co.jp
From shino at rubyforge.org Thu May 10 00:42:10 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 10 May 2007 00:42:10 -0400 (EDT)
Subject: [ap4r-devel] [163] trunk/ap4r/ap4r-devel-test.txt: test ap4r-devel
mailing list 3
Message-ID: <20070510044210.8DF4F5240C40@rubyforge.org>
Revision: 163
Author: shino
Date: 2007-05-10 00:42:10 -0400 (Thu, 10 May 2007)
Log Message:
-----------
test ap4r-devel mailing list 3
Modified Paths:
--------------
trunk/ap4r/ap4r-devel-test.txt
Modified: trunk/ap4r/ap4r-devel-test.txt
===================================================================
--- trunk/ap4r/ap4r-devel-test.txt 2007-05-10 04:38:29 UTC (rev 162)
+++ trunk/ap4r/ap4r-devel-test.txt 2007-05-10 04:42:10 UTC (rev 163)
@@ -1,2 +1,3 @@
test
test2
+test3
From kato-k at rubyforge.org Thu May 10 01:11:36 2007
From: kato-k at rubyforge.org (kato-k at rubyforge.org)
Date: Thu, 10 May 2007 01:11:36 -0400 (EDT)
Subject: [ap4r-devel] [164]
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb:
Experimentally, support block for async_dispatch.
Message-ID: <20070510051136.D02B25240C5C@rubyforge.org>
Revision: 164
Author: kato-k
Date: 2007-05-10 01:11:34 -0400 (Thu, 10 May 2007)
Log Message:
-----------
Experimentally, support block for async_dispatch.
Modified Paths:
--------------
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb 2007-05-10 04:42:10 UTC (rev 163)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb 2007-05-10 05:11:34 UTC (rev 164)
@@ -27,7 +27,7 @@
DRUBY_HOST = ENV['AP4R_DRUBY_HOST'] || 'localhost'
DRUBY_PORT = ENV['AP4R_DRUBY_PORT'] || '6438'
- DRUBY_URI = "druby://#{DRUBY_HOST}:#{DRUBY_PORT}"
+ DRUBY_URI = "druby://#{DRUBY_HOST}:#{DRUBY_PORT}"
@@default_dispatch_mode = :HTTP
@@default_rm_options = { :delivery => :once, :dispatch_mode => @@default_dispatch_mode }
@@ -43,7 +43,7 @@
#
# If the execution of +block+ finishes successfully, database transaction is committed and
# forward process of each stored message begins.
- # Forward process composed in two parts. First puts the message into a queue, secondary update
+ # Forward process composed in two parts. First puts the message into a queue, secondary update
# or delete the entry from a management table.
#
# SAF (store and forward) processing like this guarantees that any message
@@ -77,7 +77,7 @@
# Once some error occured, such as disconnect reliable-msg or server crush,
# which is smart to keep to put a message or stop to do it?
# In the case of being many async messages, the former strategy is not so good.
- #
+ #
# TODO: add delayed forward mode 2007/05/02 by shino
Thread.current[:stored_messages].each {|k,v|
__queue_put(v[:queue_name], v[:queue_message], v[:queue_headers])
@@ -124,7 +124,33 @@
# Object of argumemts (async_params, options and rm_options) will not be modified.
# Implementors (of this class and converters) should not modify them.
#
- def async_dispatch(url_options = {}, async_params = nil, rm_options = nil)
+ def async_dispatch(url_options = {}, async_params = nil, rm_options = nil, &block)
+
+ queue_name, queue_message, queue_headers = __before_block_evaluation(url_options, async_params, rm_options)
+
+ if block_given?
+ yield
+ end
+
+
+ if Thread.current[:use_saf]
+ stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers)
+
+ Thread.current[:stored_messages].store(
+ stored_message.id,
+ {
+ :queue_message => queue_message,
+ :queue_name => queue_name,
+ :queue_headers => queue_headers
+ } )
+ return stored_message.id
+ end
+
+ __queue_put(queue_name, queue_message, queue_headers)
+ end
+
+ private
+ def __before_block_evaluation(url_options, async_params, rm_options)
# TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino
if logger.debug?
logger.debug("url_options: ")
@@ -145,27 +171,9 @@
converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self)
logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"}
- queue_name = __get_queue_name(url_options, rm_options)
- queue_message = converter.make_params
- queue_headers = converter.make_rm_options
-
- if Thread.current[:use_saf]
- stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers)
-
- Thread.current[:stored_messages].store(
- stored_message.id,
- {
- :queue_message => queue_message,
- :queue_name => queue_name,
- :queue_headers => queue_headers
- } )
- return stored_message.id
- end
-
- __queue_put(queue_name, queue_message, queue_headers)
+ return __get_queue_name(url_options, rm_options), converter.make_params, converter.make_rm_options
end
- private
def __queue_put(queue_name, queue_message, queue_headers)
# TODO: can use a Queue instance repeatedly? 2007/05/02 by shino
q = ReliableMsg::Queue.new(queue_name, :drb_uri => DRUBY_URI)
From kato-k at rubyforge.org Thu May 10 03:01:45 2007
From: kato-k at rubyforge.org (kato-k at rubyforge.org)
Date: Thu, 10 May 2007 03:01:45 -0400 (EDT)
Subject: [ap4r-devel] [165] trunk/samples/HelloWorld: Refactoring,
change name space and use forwardable.
Message-ID: <20070510070145.B84305240C6D@rubyforge.org>
Revision: 165
Author: kato-k
Date: 2007-05-10 03:01:44 -0400 (Thu, 10 May 2007)
Log Message:
-----------
Refactoring, change name space and use forwardable.
Modified Paths:
--------------
trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb
Added Paths:
-----------
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
Removed Paths:
-------------
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_class.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb
Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb
===================================================================
--- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-10 05:11:34 UTC (rev 164)
+++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-10 07:01:44 UTC (rev 165)
@@ -19,15 +19,10 @@
def execute_with_block
write('Hello')
-# req = {:world_id => rand(100), :message => "World", :sleep => params[:sleep]}
-# async_dispatch({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do
-# req[:world_id] = rand(100)
-# req[:message] = "World"
-# req[:sleep] = params[:sleep]
-# req[:foo] = {:a => 1, :b => 2}
-# req[:bar] = [0, 1, 2]
-# end
-
+ #TODO: change first argument like the following sample, 2007/5/10 kato-k
+ # ap4r.async_to(:url => {:contoroller => 'foo', :action => 'bar'}, ...)
+ #
+ #TODO: support more flexible description in block, 2007/5/10 kato-k
ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do
req[:world_id] = rand(100)
req[:message] = "World"
@@ -40,7 +35,7 @@
end
def execute_with_saf
- Ap4r::AsyncController::Base.saf_delete_mode = :logical
+ Ap4r::AsyncHelper::Base.saf_delete_mode = :logical
ap4r.transaction do
write('Hello')
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-10 05:11:34 UTC (rev 164)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-10 07:01:44 UTC (rev 165)
@@ -2,12 +2,12 @@
# Copyright:: Copyright (c) 2007 Future Architect Inc.
# Licence:: MIT Licence
-require 'async_controller'
require 'ap4r/stored_message'
-require 'ap4r_class'
+require 'async_helper'
+require 'ap4r_client'
class ActionController::Base
def ap4r
- @ap4r ||= Ap4rClass.new(self)
+ @ap4r ||= ::Ap4r::Client.new(self)
end
end
Deleted: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_class.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_class.rb 2007-05-10 05:11:34 UTC (rev 164)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_class.rb 2007-05-10 07:01:44 UTC (rev 165)
@@ -1,27 +0,0 @@
-# Author:: Kiwamu Kato
-# Copyright:: Copyright (c) 2007 Future Architect Inc.
-# Licence:: MIT Licence
-
-class Ap4rClass
- include ::Ap4r::AsyncController::Base
-
- def initialize controller
- @controller = controller
- end
-
- def async_to(url_options = {}, async_params = nil, rm_options = nil, &block)
- async_dispatch(url_options, async_params,rm_options, &block)
- end
-
- def transaction active_record_class = ::Ap4r::StoredMessage, *objects, &block
- transaction_with_saf(active_record_class, *objects, &block)
- end
-
- def logger
- @controller.logger
- end
-
- def url_for(url_for_options, *parameter_for_method_reference)
- @controller.url_for(url_for_options, *parameter_for_method_reference)
- end
-end
Added: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb (rev 0)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-10 07:01:44 UTC (rev 165)
@@ -0,0 +1,26 @@
+# Author:: Kiwamu Kato
+# Copyright:: Copyright (c) 2007 Future Architect Inc.
+# Licence:: MIT Licence
+
+require 'forwardable'
+
+module Ap4r
+ class Client
+ extend Forwardable
+ include ::Ap4r::AsyncHelper::Base
+
+ def initialize controller
+ @controller = controller
+ end
+
+ def async_to(url_options = {}, async_params = nil, rm_options = nil, &block)
+ async_dispatch(url_options, async_params,rm_options, &block)
+ end
+
+ def transaction active_record_class = ::Ap4r::StoredMessage, *objects, &block
+ transaction_with_saf(active_record_class, *objects, &block)
+ end
+
+ def_delegators :@controller, :logger, :url_for
+ end
+end
Deleted: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb 2007-05-10 05:11:34 UTC (rev 164)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_controller.rb 2007-05-10 07:01:44 UTC (rev 165)
@@ -1,304 +0,0 @@
-# Author:: Shunichi Shinohara
-# Copyright:: Copyright (c) 2007 Future Architect Inc.
-# Licence:: MIT Licence
-
-require 'reliable-msg'
-#require 'ap4r/stored_message'
-
-module Ap4r
-
- # This +AsyncController+ is the Rails plugin for asynchronous processing.
- # Asynchronous logics are called via various protocols, such as XML-RPC,
- # SOAP, HTTP POST, and more. Now default protocol is HTTP POST.
- #
- # Examples: The part of calling next asynchronous logics in a controller in the HelloWorld Sample.
- #
- # req = WorldRequest.new([:world_id => 1, :message => "World"})
- # async_dispatch(req,
- # {:controller => 'async_world', :action => 'execute'},
- # :dispatch_mode => :XMLRPC }) # skippable
- #
- # render :action => 'response'
- #
- module AsyncController
-
- module Base
- Converters = {}
-
- DRUBY_HOST = ENV['AP4R_DRUBY_HOST'] || 'localhost'
- DRUBY_PORT = ENV['AP4R_DRUBY_PORT'] || '6438'
- DRUBY_URI = "druby://#{DRUBY_HOST}:#{DRUBY_PORT}"
-
- @@default_dispatch_mode = :HTTP
- @@default_rm_options = { :delivery => :once, :dispatch_mode => @@default_dispatch_mode }
- @@default_queue_prefix = "queue."
-
- mattr_accessor :default_dispatch_mode, :default_rm_options, :default_queue_prefix, :saf_delete_mode
-
- # Provides at-least-once QoS level.
- # +block+ are tipically composed of database accesses and +async_dispatch+ calls.
- # Database accesses are executed transactionallly by +active_record_class+'s transaction method.
- # In the +block+, +async_dispatch+ calls invoke NOT immediate queueing but just storing messages
- # to the database (assumed to be the same one as application uses).
- #
- # If the execution of +block+ finishes successfully, database transaction is committed and
- # forward process of each stored message begins.
- # Forward process composed in two parts. First puts the message into a queue, secondary update
- # or delete the entry from a management table.
- #
- # SAF (store and forward) processing like this guarantees that any message
- # is never lost and keeps reasonable performance (without two phase commit).
- #
- # Examples: Just call async_dispath method in this block.
- #
- # transaction_with saf do
- # req = WorldRequest.new([:world_id => 1, :message => "World"})
- # async_dispatch(req,
- # {:controller => 'async_world', :action => 'execute'},
- # :dispatch_mode => :XMLRPC }) # skippable
- #
- # render :action => 'response'
- # end
- #
- def transaction_with_saf(active_record_class = ::Ap4r::StoredMessage, *objects, &block)
-
- Thread.current[:use_saf] = true
- Thread.current[:stored_messages] = {}
-
- # store
- active_record_class ||= ::Ap4r::StoredMessage
- active_record_class.transaction(*objects, &block)
-
- # forward
- forwarded_messages = {}
- begin
-
- # TODO: reconsider forwarding strategy, 2006/10/13 kato-k
- # Once some error occured, such as disconnect reliable-msg or server crush,
- # which is smart to keep to put a message or stop to do it?
- # In the case of being many async messages, the former strategy is not so good.
- #
- # TODO: add delayed forward mode 2007/05/02 by shino
- Thread.current[:stored_messages].each {|k,v|
- __queue_put(v[:queue_name], v[:queue_message], v[:queue_headers])
- forwarded_messages[k] = v
- }
- rescue Exception => err
- # Don't raise any Exception. Application logic has already completed and messages are saved.
- logger.warn("Failed to put a message into queue: #{err}")
- end
-
- begin
- StoredMessage.transaction do
- options = {:delete_mode => @@saf_delete_mode || :physical}
- forwarded_messages.keys.each {|id|
- ::Ap4r::StoredMessage.destroy_if_exists(id, options)
- }
- end
- rescue Exception => err
- # Don't raise any Exception. Application logic has already completed and messages are saved.
- logger.warn("Failed to put a message into queue: #{err}")
- end
-
- ensure
- Thread.current[:use_saf] = false
- Thread.current[:stored_messages] = nil
- end
-
- # Queue a message for next asynchronous logic. Some options are supported.
- #
- # Use options to specify target url, etc.
- # Accurate meanings are defined by a individual converter class.
- # * :controller (name of next logic)
- # * :action (name of next logic)
- #
- # Use rm_options to pass parameter in queue-put.
- # Listings below are AP4R extended options.
- # See the reliable-msg docuememt for more details.
- # * :target_url (URL of target, prevail over :controller)
- # * :target_action (action of target, prevail over :action)
- # * :target_method (HTTP method, e.g. "GET", "POST", etc.)
- # * :dispatch_mode (protocol in dispatching)
- # * :queue_name (prevail over :controller and :action)
- #
- # Object of argumemts (async_params, options and rm_options) will not be modified.
- # Implementors (of this class and converters) should not modify them.
- #
- def async_dispatch(url_options = {}, async_params = nil, rm_options = nil, &block)
-
- queue_name, queue_message, queue_headers = __before_block_evaluation(url_options, async_params, rm_options)
-
- if block_given?
- yield
- end
-
-
- if Thread.current[:use_saf]
- stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers)
-
- Thread.current[:stored_messages].store(
- stored_message.id,
- {
- :queue_message => queue_message,
- :queue_name => queue_name,
- :queue_headers => queue_headers
- } )
- return stored_message.id
- end
-
- __queue_put(queue_name, queue_message, queue_headers)
- end
-
- private
- def __before_block_evaluation(url_options, async_params, rm_options)
- # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino
- if logger.debug?
- logger.debug("url_options: ")
- logger.debug(url_options.inspect)
- logger.debug("async_params: ")
- logger.debug(async_params.inspect)
- logger.debug("rm_options: ")
- logger.debug(rm_options.inspect)
- end
-
- # TODO: clone it, 2006/10/16 shino
- url_options ||= {}
- url_options[:controller] ||= self.controller_path.gsub("/", ".")
- rm_options = @@default_rm_options.merge(rm_options || {})
-
- # Only async_params is not cloned. options and rm_options are cloned before now.
- # This is a current contract between this class and converter classes.
- converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self)
- logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"}
-
- return __get_queue_name(url_options, rm_options), converter.make_params, converter.make_rm_options
- end
-
- def __queue_put(queue_name, queue_message, queue_headers)
- # TODO: can use a Queue instance repeatedly? 2007/05/02 by shino
- q = ReliableMsg::Queue.new(queue_name, :drb_uri => DRUBY_URI)
- q.put(queue_message, queue_headers)
- end
-
- def __get_queue_name(options, rm_options)
- rm_options[:queue_name] ||=
- @@default_queue_prefix.clone.concat(options[:controller].to_s).concat('.').concat(options[:action].to_s)
- rm_options[:queue_name]
- end
-
- end
-
- module Converters #:nodoc:
-
- # A base class for converter classes.
- # Responsibilities of subclasses are as folows
- # * by +make_params+, convert async_params to appropriate object
- # * by +make_rm_options+, make appropriate +Hash+ passed by ReliableMsg::Queue#put
- class Base
-
- # Difine a constant +DISPATCH_MODE+ to value 'mode_symbol' and
- # add self to a Converters list.
- def self.dispatch_mode(mode_symbol)
- self.const_set(:DISPATCH_MODE, mode_symbol)
- ::Ap4r::AsyncController::Base::Converters[mode_symbol] = self
- end
-
- def initialize(url_options, async_params, rm_options, url_for_handler)
- @url_options = url_options
- @async_params = async_params
- @rm_options = rm_options
- @url_for_handler = url_for_handler
- end
-
- # Returns a object which passed to ReliableMsg::Queue.put(message, headers)'s
- # first argument +message+.
- # Should be implemented by subclasses.
- def make_params
- raise 'must be implemented in subclasses'
- end
-
- # Returns a object which passed to ReliableMsg::Queue.put(message, headers)'s
- # second argument +headers+.
- # Should be implemented by subclasses.
- def make_rm_options
- raise 'must be implemented in subclasses'
- end
-
- private
- # helper method for ActionController#url_for
- def url_for(url_for_options, *parameter_for_method_reference)
- @url_for_handler.url_for(url_for_options, *parameter_for_method_reference)
- end
-
- end
-
- class Http < Base
- dispatch_mode :HTTP
-
- def make_params
- @async_params
- end
-
- def make_rm_options
- @rm_options[:target_url] ||= url_for(@url_options)
- @rm_options[:target_method] ||= 'POST'
- #TODO: make option key to specify HTTP headers, 2006/10/16 shino
- @rm_options
- end
- end
-
- class WebService < Base
- def make_params
- message_obj = {}
- @async_params.each_pair{|k,v| message_obj[k.to_sym]=v}
- message_obj
- end
-
- def make_rm_options
- @rm_options[:target_url] ||= target_url_name
- @rm_options[:target_action] ||= action_api_name
- @rm_options
- end
-
- def action_api_name
- action_method_name = @url_options[:action]
- action_method_name.camelcase
- end
-
- def options_without_action
- new_opts = @url_options.dup
- new_opts[:action] = nil
- new_opts
- end
-
- end
-
- class XmlRpc < WebService
- dispatch_mode :XMLRPC
-
- def target_url_name
- url_for(options_without_action) + rails_api_url_suffix
- end
-
- private
- def rails_api_url_suffix
- '/api'
- end
- end
-
- class SOAP < WebService
- dispatch_mode :SOAP
-
- def target_url_name
- url_for(options_without_action) + rails_wsdl_url_suffix
- end
-
- private
- def rails_wsdl_url_suffix
- '/service.wsdl'
- end
- end
-
- end
- end
-end
Added: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb (rev 0)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-10 07:01:44 UTC (rev 165)
@@ -0,0 +1,303 @@
+# Author:: Shunichi Shinohara
+# Copyright:: Copyright (c) 2007 Future Architect Inc.
+# Licence:: MIT Licence
+
+require 'reliable-msg'
+
+module Ap4r
+
+ # This +AsyncHelper+ is the Rails plugin for asynchronous processing.
+ # Asynchronous logics are called via various protocols, such as XML-RPC,
+ # SOAP, HTTP POST, and more. Now default protocol is HTTP POST.
+ #
+ # Examples: The part of calling next asynchronous logics in a controller in the HelloWorld Sample.
+ #
+ # req = WorldRequest.new([:world_id => 1, :message => "World"})
+ # async_dispatch(req,
+ # {:controller => 'async_world', :action => 'execute'},
+ # :dispatch_mode => :XMLRPC }) # skippable
+ #
+ # render :action => 'response'
+ #
+ module AsyncHelper
+
+ module Base
+ Converters = {}
+
+ DRUBY_HOST = ENV['AP4R_DRUBY_HOST'] || 'localhost'
+ DRUBY_PORT = ENV['AP4R_DRUBY_PORT'] || '6438'
+ DRUBY_URI = "druby://#{DRUBY_HOST}:#{DRUBY_PORT}"
+
+ @@default_dispatch_mode = :HTTP
+ @@default_rm_options = { :delivery => :once, :dispatch_mode => @@default_dispatch_mode }
+ @@default_queue_prefix = "queue."
+
+ mattr_accessor :default_dispatch_mode, :default_rm_options, :default_queue_prefix, :saf_delete_mode
+
+ # Provides at-least-once QoS level.
+ # +block+ are tipically composed of database accesses and +async_dispatch+ calls.
+ # Database accesses are executed transactionallly by +active_record_class+'s transaction method.
+ # In the +block+, +async_dispatch+ calls invoke NOT immediate queueing but just storing messages
+ # to the database (assumed to be the same one as application uses).
+ #
+ # If the execution of +block+ finishes successfully, database transaction is committed and
+ # forward process of each stored message begins.
+ # Forward process composed in two parts. First puts the message into a queue, secondary update
+ # or delete the entry from a management table.
+ #
+ # SAF (store and forward) processing like this guarantees that any message
+ # is never lost and keeps reasonable performance (without two phase commit).
+ #
+ # Examples: Just call async_dispath method in this block.
+ #
+ # transaction_with saf do
+ # req = WorldRequest.new([:world_id => 1, :message => "World"})
+ # async_dispatch(req,
+ # {:controller => 'async_world', :action => 'execute'},
+ # :dispatch_mode => :XMLRPC }) # skippable
+ #
+ # render :action => 'response'
+ # end
+ #
+ def transaction_with_saf(active_record_class = ::Ap4r::StoredMessage, *objects, &block)
+
+ Thread.current[:use_saf] = true
+ Thread.current[:stored_messages] = {}
+
+ # store
+ active_record_class ||= ::Ap4r::StoredMessage
+ active_record_class.transaction(*objects, &block)
+
+ # forward
+ forwarded_messages = {}
+ begin
+
+ # TODO: reconsider forwarding strategy, 2006/10/13 kato-k
+ # Once some error occured, such as disconnect reliable-msg or server crush,
+ # which is smart to keep to put a message or stop to do it?
+ # In the case of being many async messages, the former strategy is not so good.
+ #
+ # TODO: add delayed forward mode 2007/05/02 by shino
+ Thread.current[:stored_messages].each {|k,v|
+ __queue_put(v[:queue_name], v[:queue_message], v[:queue_headers])
+ forwarded_messages[k] = v
+ }
+ rescue Exception => err
+ # Don't raise any Exception. Application logic has already completed and messages are saved.
+ logger.warn("Failed to put a message into queue: #{err}")
+ end
+
+ begin
+ StoredMessage.transaction do
+ options = {:delete_mode => @@saf_delete_mode || :physical}
+ forwarded_messages.keys.each {|id|
+ ::Ap4r::StoredMessage.destroy_if_exists(id, options)
+ }
+ end
+ rescue Exception => err
+ # Don't raise any Exception. Application logic has already completed and messages are saved.
+ logger.warn("Failed to put a message into queue: #{err}")
+ end
+
+ ensure
+ Thread.current[:use_saf] = false
+ Thread.current[:stored_messages] = nil
+ end
+
+ # Queue a message for next asynchronous logic. Some options are supported.
+ #
+ # Use options to specify target url, etc.
+ # Accurate meanings are defined by a individual converter class.
+ # * :controller (name of next logic)
+ # * :action (name of next logic)
+ #
+ # Use rm_options to pass parameter in queue-put.
+ # Listings below are AP4R extended options.
+ # See the reliable-msg docuememt for more details.
+ # * :target_url (URL of target, prevail over :controller)
+ # * :target_action (action of target, prevail over :action)
+ # * :target_method (HTTP method, e.g. "GET", "POST", etc.)
+ # * :dispatch_mode (protocol in dispatching)
+ # * :queue_name (prevail over :controller and :action)
+ #
+ # Object of argumemts (async_params, options and rm_options) will not be modified.
+ # Implementors (of this class and converters) should not modify them.
+ #
+ def async_dispatch(url_options = {}, async_params = nil, rm_options = nil, &block)
+
+ queue_name, queue_message, queue_headers = __before_block_evaluation(url_options, async_params, rm_options)
+
+ if block_given?
+ yield
+ end
+
+
+ if Thread.current[:use_saf]
+ stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers)
+
+ Thread.current[:stored_messages].store(
+ stored_message.id,
+ {
+ :queue_message => queue_message,
+ :queue_name => queue_name,
+ :queue_headers => queue_headers
+ } )
+ return stored_message.id
+ end
+
+ __queue_put(queue_name, queue_message, queue_headers)
+ end
+
+ private
+ def __before_block_evaluation(url_options, async_params, rm_options)
+ # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino
+ if logger.debug?
+ logger.debug("url_options: ")
+ logger.debug(url_options.inspect)
+ logger.debug("async_params: ")
+ logger.debug(async_params.inspect)
+ logger.debug("rm_options: ")
+ logger.debug(rm_options.inspect)
+ end
+
+ # TODO: clone it, 2006/10/16 shino
+ url_options ||= {}
+ url_options[:controller] ||= self.controller_path.gsub("/", ".")
+ rm_options = @@default_rm_options.merge(rm_options || {})
+
+ # Only async_params is not cloned. options and rm_options are cloned before now.
+ # This is a current contract between this class and converter classes.
+ converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self)
+ logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"}
+
+ return __get_queue_name(url_options, rm_options), converter.make_params, converter.make_rm_options
+ end
+
+ def __queue_put(queue_name, queue_message, queue_headers)
+ # TODO: can use a Queue instance repeatedly? 2007/05/02 by shino
+ q = ReliableMsg::Queue.new(queue_name, :drb_uri => DRUBY_URI)
+ q.put(queue_message, queue_headers)
+ end
+
+ def __get_queue_name(options, rm_options)
+ rm_options[:queue_name] ||=
+ @@default_queue_prefix.clone.concat(options[:controller].to_s).concat('.').concat(options[:action].to_s)
+ rm_options[:queue_name]
+ end
+
+ end
+
+ module Converters #:nodoc:
+
+ # A base class for converter classes.
+ # Responsibilities of subclasses are as folows
+ # * by +make_params+, convert async_params to appropriate object
+ # * by +make_rm_options+, make appropriate +Hash+ passed by ReliableMsg::Queue#put
+ class Base
+
+ # Difine a constant +DISPATCH_MODE+ to value 'mode_symbol' and
+ # add self to a Converters list.
+ def self.dispatch_mode(mode_symbol)
+ self.const_set(:DISPATCH_MODE, mode_symbol)
+ ::Ap4r::AsyncHelper::Base::Converters[mode_symbol] = self
+ end
+
+ def initialize(url_options, async_params, rm_options, url_for_handler)
+ @url_options = url_options
+ @async_params = async_params
+ @rm_options = rm_options
+ @url_for_handler = url_for_handler
+ end
+
+ # Returns a object which passed to ReliableMsg::Queue.put(message, headers)'s
+ # first argument +message+.
+ # Should be implemented by subclasses.
+ def make_params
+ raise 'must be implemented in subclasses'
+ end
+
+ # Returns a object which passed to ReliableMsg::Queue.put(message, headers)'s
+ # second argument +headers+.
+ # Should be implemented by subclasses.
+ def make_rm_options
+ raise 'must be implemented in subclasses'
+ end
+
+ private
+ # helper method for ActionController#url_for
+ def url_for(url_for_options, *parameter_for_method_reference)
+ @url_for_handler.url_for(url_for_options, *parameter_for_method_reference)
+ end
+
+ end
+
+ class Http < Base
+ dispatch_mode :HTTP
+
+ def make_params
+ @async_params
+ end
+
+ def make_rm_options
+ @rm_options[:target_url] ||= url_for(@url_options)
+ @rm_options[:target_method] ||= 'POST'
+ #TODO: make option key to specify HTTP headers, 2006/10/16 shino
+ @rm_options
+ end
+ end
+
+ class WebService < Base
+ def make_params
+ message_obj = {}
+ @async_params.each_pair{|k,v| message_obj[k.to_sym]=v}
+ message_obj
+ end
+
+ def make_rm_options
+ @rm_options[:target_url] ||= target_url_name
+ @rm_options[:target_action] ||= action_api_name
+ @rm_options
+ end
+
+ def action_api_name
+ action_method_name = @url_options[:action]
+ action_method_name.camelcase
+ end
+
+ def options_without_action
+ new_opts = @url_options.dup
+ new_opts[:action] = nil
+ new_opts
+ end
+
+ end
+
+ class XmlRpc < WebService
+ dispatch_mode :XMLRPC
+
+ def target_url_name
+ url_for(options_without_action) + rails_api_url_suffix
+ end
+
+ private
+ def rails_api_url_suffix
+ '/api'
+ end
+ end
+
+ class SOAP < WebService
+ dispatch_mode :SOAP
+
+ def target_url_name
+ url_for(options_without_action) + rails_wsdl_url_suffix
+ end
+
+ private
+ def rails_wsdl_url_suffix
+ '/service.wsdl'
+ end
+ end
+
+ end
+ end
+end
From shinohara.shunichi at future.co.jp Thu May 10 03:18:26 2007
From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp)
Date: Thu, 10 May 2007 16:18:26 +0900
Subject: [ap4r-devel] [163] trunk/ap4r/ap4r-devel-test.txt: test
ap4r-develmailing list 3
In-Reply-To: <20070510044210.8DF4F5240C40@rubyforge.org>
References: <20070510044210.8DF4F5240C40@rubyforge.org>
Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDEC@045MAIL.future.co.jp>
reply testing
-----Original Message-----
From: ap4r-devel-bounces at rubyforge.org [mailto:ap4r-devel-bounces at rubyforge.org] On Behalf Of shino at rubyforge.org
Sent: Thursday, May 10, 2007 1:42 PM
To: ap4r-devel at rubyforge.org
Subject: [ap4r-devel] [163] trunk/ap4r/ap4r-devel-test.txt: test ap4r-develmailing list 3
Revision: 163
Author: shino
Date: 2007-05-10 00:42:10 -0400 (Thu, 10 May 2007)
Log Message:
-----------
test ap4r-devel mailing list 3
Modified Paths:
--------------
trunk/ap4r/ap4r-devel-test.txt
Modified: trunk/ap4r/ap4r-devel-test.txt
===================================================================
--- trunk/ap4r/ap4r-devel-test.txt 2007-05-10 04:38:29 UTC (rev 162)
+++ trunk/ap4r/ap4r-devel-test.txt 2007-05-10 04:42:10 UTC (rev 163)
@@ -1,2 +1,3 @@
test
test2
+test3
_______________________________________________
Ap4r-devel mailing list
Ap4r-devel at rubyforge.org
http://rubyforge.org/mailman/listinfo/ap4r-devel
From shinohara.shunichi at future.co.jp Thu May 10 03:21:42 2007
From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp)
Date: Thu, 10 May 2007 16:21:42 +0900
Subject: [ap4r-devel] test of reply address
Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDEF@045MAIL.future.co.jp>
no message
---------------------------------
SHINOHARA, Shun'ichi
Future Architect, Inc.
1-2-2 Osaki Shinagawa-Ku
Tokyo, JAPAN (ZIP 141-0032)
070-6991-0765 (cell phone)
shinohara.shunichi at future.co.jp
From shinohara.shunichi at future.co.jp Thu May 10 03:23:21 2007
From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp)
Date: Thu, 10 May 2007 16:23:21 +0900
Subject: [ap4r-devel] test of reply address
In-Reply-To: <14CE73B79D552644B7CBEF0428763DF60247FDEF@045MAIL.future.co.jp>
References: <14CE73B79D552644B7CBEF0428763DF60247FDEF@045MAIL.future.co.jp>
Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDF1@045MAIL.future.co.jp>
this is a reply message.
-----Original Message-----
From: ap4r-devel-bounces at rubyforge.org [mailto:ap4r-devel-bounces at rubyforge.org] On Behalf Of shinohara.shunichi at future.co.jp
Sent: Thursday, May 10, 2007 4:22 PM
To: ap4r-devel at rubyforge.org
Subject: [ap4r-devel] test of reply address
no message
---------------------------------
SHINOHARA, Shun'ichi
Future Architect, Inc.
1-2-2 Osaki Shinagawa-Ku
Tokyo, JAPAN (ZIP 141-0032)
070-6991-0765 (cell phone)
shinohara.shunichi at future.co.jp
_______________________________________________
ap4r-devel mailing list
ap4r-devel at rubyforge.org
http://rubyforge.org/mailman/listinfo/ap4r-devel
From shinohara.shunichi at future.co.jp Thu May 10 03:33:57 2007
From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp)
Date: Thu, 10 May 2007 16:33:57 +0900
Subject: [ap4r-devel 18] test of sequential number
Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDF7@045MAIL.future.co.jp>
no message
---------------------------------
SHINOHARA, Shun'ichi
Future Architect, Inc.
1-2-2 Osaki Shinagawa-Ku
Tokyo, JAPAN (ZIP 141-0032)
070-6991-0765 (cell phone)
shinohara.shunichi at future.co.jp
From shinohara.shunichi at future.co.jp Thu May 10 03:43:42 2007
From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp)
Date: Thu, 10 May 2007 16:43:42 +0900
Subject: [ap4r-devel:19] test of sequential number #2
Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDFB@045MAIL.future.co.jp>
no message
---------------------------------
SHINOHARA, Shun'ichi
Future Architect, Inc.
1-2-2 Osaki Shinagawa-Ku
Tokyo, JAPAN (ZIP 141-0032)
070-6991-0765 (cell phone)
shinohara.shunichi at future.co.jp
From shinohara.shunichi at future.co.jp Thu May 10 03:49:58 2007
From: shinohara.shunichi at future.co.jp (shinohara.shunichi at future.co.jp)
Date: Thu, 10 May 2007 16:49:58 +0900
Subject: [ap4r-devel:20] Re: test of sequential number #2
In-Reply-To: <14CE73B79D552644B7CBEF0428763DF60247FDFB@045MAIL.future.co.jp>
References: <14CE73B79D552644B7CBEF0428763DF60247FDFB@045MAIL.future.co.jp>
Message-ID: <14CE73B79D552644B7CBEF0428763DF60247FDFE@045MAIL.future.co.jp>
test of reply with squential number
-----Original Message-----
From: ap4r-devel-bounces at rubyforge.org [mailto:ap4r-devel-bounces at rubyforge.org] On Behalf Of shinohara.shunichi at future.co.jp
Sent: Thursday, May 10, 2007 4:44 PM
To: ap4r-devel at rubyforge.org
Subject: [ap4r-devel:19] test of sequential number #2
no message
---------------------------------
SHINOHARA, Shun'ichi
Future Architect, Inc.
1-2-2 Osaki Shinagawa-Ku
Tokyo, JAPAN (ZIP 141-0032)
070-6991-0765 (cell phone)
shinohara.shunichi at future.co.jp
_______________________________________________
ap4r-devel mailing list
ap4r-devel at rubyforge.org
http://rubyforge.org/mailman/listinfo/ap4r-devel
From kato-k at rubyforge.org Thu May 10 03:58:45 2007
From: kato-k at rubyforge.org (kato-k at rubyforge.org)
Date: Thu, 10 May 2007 03:58:45 -0400 (EDT)
Subject: [ap4r-devel] [166]
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb:
Refactoring.
Message-ID: <20070510075845.E4F305240C60@rubyforge.org>
Revision: 166
Author: kato-k
Date: 2007-05-10 03:58:45 -0400 (Thu, 10 May 2007)
Log Message:
-----------
Refactoring.
Modified Paths:
--------------
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-10 07:01:44 UTC (rev 165)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-10 07:58:45 UTC (rev 166)
@@ -13,14 +13,9 @@
@controller = controller
end
- def async_to(url_options = {}, async_params = nil, rm_options = nil, &block)
- async_dispatch(url_options, async_params,rm_options, &block)
- end
-
- def transaction active_record_class = ::Ap4r::StoredMessage, *objects, &block
- transaction_with_saf(active_record_class, *objects, &block)
- end
-
def_delegators :@controller, :logger, :url_for
+
+ alias :async_to :async_dispatch
+ alias :transaction :transaction_with_saf
end
end
From shino at rubyforge.org Thu May 10 04:48:31 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 10 May 2007 04:48:31 -0400 (EDT)
Subject: [ap4r-devel] [167]
trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb:
refactoring: lengthen a varivable name to avoid accidental
name collision
Message-ID: <20070510084831.3E8C65240952@rubyforge.org>
Revision: 167
Author: shino
Date: 2007-05-10 04:48:30 -0400 (Thu, 10 May 2007)
Log Message:
-----------
refactoring: lengthen a varivable name to avoid accidental name collision
Modified Paths:
--------------
trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-10 07:58:45 UTC (rev 166)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-10 08:48:30 UTC (rev 167)
@@ -8,6 +8,6 @@
class ActionController::Base
def ap4r
- @ap4r ||= ::Ap4r::Client.new(self)
+ @ap4r_client ||= ::Ap4r::Client.new(self)
end
end
From shino at rubyforge.org Thu May 10 05:36:42 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 10 May 2007 05:36:42 -0400 (EDT)
Subject: [ap4r-devel] [168] trunk/ap4r/lib/ap4r/dispatcher.rb: Refactoring:
extract methods and restructure methods.
Message-ID: <20070510093645.8C1465240978@rubyforge.org>
Revision: 168
Author: shino
Date: 2007-05-10 05:36:38 -0400 (Thu, 10 May 2007)
Log Message:
-----------
Refactoring: extract methods and restructure methods.
Add Rdoc.
Modified Paths:
--------------
trunk/ap4r/lib/ap4r/dispatcher.rb
Modified: trunk/ap4r/lib/ap4r/dispatcher.rb
===================================================================
--- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-10 08:48:30 UTC (rev 167)
+++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-10 09:36:38 UTC (rev 168)
@@ -26,12 +26,20 @@
@@logger
end
- # Stores Dispatchers::Base's subclasses.
+ # storage for Dispatchers::Base's subclasses.
@@subclasses = {}
+
+ # Stores +klass+ for a dispatch mode +mode+
+ # Each +klass+ is used to create instances to handle dispatching messages.
def self.register_dispatcher_class(mode, klass)
@@subclasses[mode] = klass
end
+ # Sum of each dispatcher's target queues.
+ def targets
+ @dispatch_targets
+ end
+
def initialize(queue_manager, config, logger_obj)
@qm = queue_manager
@config = config
@@ -41,12 +49,9 @@
@dispatch_targets = ""
end
- # Sum of each dispatcher's target queues.
- def targets
- @dispatch_targets
- end
-
# Starts every dispatcher.
+ # If an exception is detected, this method raise it through with logging.
+ #
def start
begin
logger.info{ "about to start dispatchers with config\n#{@config.to_yaml}" }
@@ -81,18 +86,22 @@
private
- def get_dispather_instance(dispatch_mode)
+ # Creates and returns an appropriate instace.
+ # If no class for +dispatch_mode+, raises an exception.
+ def get_dispather_instance(dispatch_mode, message, conf)
klass = @@subclasses[dispatch_mode]
raise "undefined dispatch mode #{m.headers[:mode]}" unless klass
- klass.new
+ klass.new(message, conf)
end
+ # Defines the general structure for each dispatcher thread
+ # from begging to end.
def dispatching_loop(group, conf, index)
group.add(Thread.current)
mq = ::ReliableMsg::MultiQueue.new(conf["targets"])
logger.info{ "start dispatcher: targets= #{mq}, index= #{index})" }
until Thread.current[:dying]
- # TODO: better to change sleep interval depending on last result? 2007/05/09 by shino
+ # TODO: change sleep interval depending on last result? 2007/05/09 by shino
sleep 0.1
# logger.debug{ "try dispatch #{mq} #{mq.name}" }
# TODO: needs timeout?, 2006/10/16 shino
@@ -103,7 +112,7 @@
break
end
logger.debug{"dispatcher get message\n#{m.to_yaml}"}
- response = get_dispather_instance(m.headers[:dispatch_mode]).call(m, conf)
+ response = get_dispather_instance(m.headers[:dispatch_mode], m, conf).call
logger.debug{"dispatcher get response\n#{response.to_yaml}"}
}
rescue Exception => err
@@ -131,35 +140,61 @@
::Ap4r::Dispatchers.register_dispatcher_class(mode_symbol, self)
end
- def call(message, conf)
+ def initialize(message, conf)
+ @message = message
+ @conf = conf
+ end
+
+ def call
+ # TODO: rename to more appropriate one 2007/05/10 by shino
+ self.modify_message
+ self.invoke
+ self.varidate_response
+ self.response
+ end
+
+ def modify_message
+ # nop
+ end
+
+ def invoke
+ # TODO: rename to more appropriate one 2007/05/10 by shino
raise 'must be implemented in subclasses'
end
+ def varidate_response
+ # nop
+ end
+
+ def response
+ @response
+ end
+
+ private
def logger
::Ap4r::Dispatchers.logger
end
end
- # Dispatch login via HTTP.
+ # Dispatch logic via HTTP.
class Http < Base
dispatch_mode :HTTP
- # Dispatches via a HTTP protocol.
- # Current implementation uses POST method, irrespectively options[:target_method]
+ # Dispatches via a raw HTTP protocol.
+ # Current implementation uses only a POST method, irrespectively
+ # options[:target_method].
#
- # Determination of "success" is two fold
- # * status code should be 200, other codes (including 201-2xx) are treated as error
- # * when status code is 200, body should include a string "true"
- def call(message, conf)
+ # Determination of "success" is two fold:
+ # * status code should be exactly 200, other codes (including 201-2xx) are
+ # treated as error, and
+ # * body should include a string "true"
+ def invoke
#TODO: should be added some request headers e.g. User-Agent and Accept, 2006/10/12 shino
#TODO: Now supports POST only, 2006/10/12 shino
- @response = Net::HTTP.post_form(URI.parse(message[:target_url]),
- message.object)
- varidate_response
- @response
+ @response = Net::HTTP.post_form(URI.parse(@message[:target_url]),
+ @message.object)
end
- private
def varidate_response
logger.debug{"response status [#{@response.code} #{@response.message}]"}
varidate_response_status(Net::HTTPOK)
@@ -197,23 +232,25 @@
class XmlRpc < Base
dispatch_mode :XMLRPC
- def call(message, conf)
- endpoint = message[:target_url]
+
+ def invoke
+ endpoint = @message[:target_url]
client = XMLRPC::Client.new2(endpoint)
- success, response = client.call2(message[:target_action], message.object)
- raise response unless success
- response
+ @success, @response = client.call2(@message[:target_action], @message.object)
end
+
+ def varidate_response
+ raise @response unless @success
+ end
end
class SOAP < Base
dispatch_mode :SOAP
- def call(message, conf)
- logger.debug{message[:target_url]}
+
+ def invoke
# TODO: nice to cache drivers probably 2007/05/09 by shino
- driver = ::SOAP::WSDLDriverFactory.new(message[:target_url]).create_rpc_driver
- logger.debug{driver}
- driver.send(message[:target_action], message.object)
+ driver = ::SOAP::WSDLDriverFactory.new(@message[:target_url]).create_rpc_driver
+ driver.send(@message[:target_action], @message.object)
end
end
From shino at rubyforge.org Thu May 10 23:11:39 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 10 May 2007 23:11:39 -0400 (EDT)
Subject: [ap4r-devel] [169] trunk/ap4r/lib/ap4r/dispatcher.rb: Implemented
url modification function briefly.
Message-ID: <20070511031139.28AE85240A99@rubyforge.org>
Revision: 169
Author: shino
Date: 2007-05-10 23:11:38 -0400 (Thu, 10 May 2007)
Log Message:
-----------
Implemented url modification function briefly.
Presenct implementation takes proc string in yaml,
evals it and calls it.
Also made Some refactorings and comment addtion.
Modified Paths:
--------------
trunk/ap4r/lib/ap4r/dispatcher.rb
Modified: trunk/ap4r/lib/ap4r/dispatcher.rb
===================================================================
--- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-10 09:36:38 UTC (rev 168)
+++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-11 03:11:38 UTC (rev 169)
@@ -42,7 +42,7 @@
def initialize(queue_manager, config, logger_obj)
@qm = queue_manager
- @config = config
+ @config = config # (typically) dispatcher section of queues.cfg
@@logger ||= logger_obj
raise "no configuration specified" unless @config
@group = ThreadGroup.new
@@ -88,10 +88,10 @@
# Creates and returns an appropriate instace.
# If no class for +dispatch_mode+, raises an exception.
- def get_dispather_instance(dispatch_mode, message, conf)
+ def get_dispather_instance(dispatch_mode, message, conf_per_targets)
klass = @@subclasses[dispatch_mode]
raise "undefined dispatch mode #{m.headers[:mode]}" unless klass
- klass.new(message, conf)
+ klass.new(message, conf_per_targets)
end
# Defines the general structure for each dispatcher thread
@@ -129,8 +129,12 @@
# A base class for dispathcer classes.
- # Responsibilities of subclasses are as folows
- # * +call+
+ # Responsibilities of subclasses is to implement following methods, only +invoke+
+ # is mandatory and others are optional (no operations by default).
+ # * +modify_message+ to preprocess a message, e.g. rewirte URL or discard message.
+ # * +invoke+ to execute main logic, e.g. HTTP POST call. *mandatory*
+ # * +varidate_response+ to judge whether +invoke+ finished successfully.
+ # * +response+ to return the result of +invoke+ process.
class Base
# Difine a constant +DISPATCH_MODE+ to value 'mode_symbol' and
@@ -148,13 +152,16 @@
def call
# TODO: rename to more appropriate one 2007/05/10 by shino
self.modify_message
+ logger.debug{"Ap4r::Dispatcher after modification\n#{@message.to_yaml}"}
self.invoke
self.varidate_response
self.response
end
def modify_message
- # nop
+ modification_rules = @conf["modify_rules"]
+ return unless modification_rules
+ modify_url(modification_rules)
end
def invoke
@@ -174,6 +181,15 @@
def logger
::Ap4r::Dispatchers.logger
end
+
+ def modify_url(modification_rules)
+ proc_for_url = modification_rules["url"]
+ return unless proc_for_url
+
+ url = URI.parse(@message.headers[:target_url])
+ eval(proc_for_url).call(url)
+ @message.headers[:target_url] = url.to_s
+ end
end
# Dispatch logic via HTTP.
@@ -189,8 +205,9 @@
# treated as error, and
# * body should include a string "true"
def invoke
- #TODO: should be added some request headers e.g. User-Agent and Accept, 2006/10/12 shino
- #TODO: Now supports POST only, 2006/10/12 shino
+ # TODO: should be added some request headers 2006/10/12 shino
+ # e.g. X-Ap4r-Version, Accept(need it?)
+ # TODO: Now supports POST only, 2006/10/12 shino
@response = Net::HTTP.post_form(URI.parse(@message[:target_url]),
@message.object)
end
@@ -201,12 +218,13 @@
varidate_response_body(/true/)
end
- # Checks the response status is kind of +status_kind+
+ # Checks whether the response status is a kind of +status_kind+.
# +status_kind+ should be one of Net::HTTPRespose's subclasses.
def varidate_response_status(status_kind)
#TODO: make the difinition of success variable, 2006/10/13 shino
unless @response.kind_of?(status_kind)
- error_message = "HTTP Response FAILURE, status [#{@response.code} #{@response.message}]"
+ error_message = "HTTP Response FAILURE, " +
+ "status [#{@response.code} #{@response.message}]"
logger.error(error_message)
logger.info{@response.to_yaml}
#TODO: must create AP4R specific Exception class, 2006/10/12 shino
@@ -214,12 +232,12 @@
end
end
- # Checks the response body includes +pattern+.
+ # Checks whether the response body includes +pattern+.
# +pattern+ should be a regular expression.
def varidate_response_body(pattern)
unless @response.body =~ pattern
- error_message = "HTTP Response FAILURE, status"
- + " [#{@response.code} #{@response.message}], body [#{@response.body}]"
+ error_message = "HTTP Response FAILURE, status" +
+ " [#{@response.code} #{@response.message}], body [#{@response.body}]"
#TODO: Refactor error logging, 2006/10/13 shino
logger.error(error_message)
logger.info{@response.to_yaml}
From kato-k at rubyforge.org Fri May 11 06:42:53 2007
From: kato-k at rubyforge.org (kato-k at rubyforge.org)
Date: Fri, 11 May 2007 06:42:53 -0400 (EDT)
Subject: [ap4r-devel] [170] trunk/samples/HelloWorld: experimental
implementation for async_to method with block,
jsut block evaluation.
Message-ID: <20070511104253.65AC45240977@rubyforge.org>
Revision: 170
Author: kato-k
Date: 2007-05-11 06:42:53 -0400 (Fri, 11 May 2007)
Log Message:
-----------
experimental implementation for async_to method with block, jsut block evaluation.
Modified Paths:
--------------
trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
Added Paths:
-----------
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb
Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb
===================================================================
--- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-11 03:11:38 UTC (rev 169)
+++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-11 10:42:53 UTC (rev 170)
@@ -23,12 +23,46 @@
# ap4r.async_to(:url => {:contoroller => 'foo', :action => 'bar'}, ...)
#
#TODO: support more flexible description in block, 2007/5/10 kato-k
- ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do
- req[:world_id] = rand(100)
- req[:message] = "World"
- req[:sleep] = params[:sleep]
- req[:foo] = {:a => 1, :b => 2}
- req[:bar] = [0, 1, 2]
+ ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do |b|
+
+ # message body
+ # basically, use block argumennt
+ b.hoge1 = "hoge1"
+ b[:hoge2] = "hoge2"
+
+ #b.hoge3 "hoge3" # not support
+ b.id = 1 # method "id" is also available.
+
+ #TODO support ActiveRecord object, 2007/5/11 kato-k
+ b.order = @order #?
+
+ # message header
+ b.headers[:target_url] = "http://..."
+ b.headers[:priority] = 2
+ b.headers[:druby_url] = "druby://..."
+
+ #TODO support http headers, 2007/5/11 kato-k
+ #b.http_headers[:accept] = "text/plain"
+ #b.http_headers["content-type"] = "application/json"
+ #b.headers[:http_header_accept] = "text/plain"
+
+ #tricky pattern, but definition in method arguments is necessary.
+ req[:_num] = rand(100)
+ req[:_str] = "World"
+ req[:_hash] = {:a => 1, :b => 2}
+ req[:_array] = [0, 1, 2]
+
+
+ #TODO support various request formats such as xml and json, 2007/5/11 kato-k
+ #b.queue_message = @order, :include => :details, :format => :json
+ #b.queue_message = @order, :include => :details, :format => :xml
+
+
+ # contens of message are referable
+ p b.queue_name
+ p b.queue_message
+ p b.queue_headers
+
end
render :nothing => true
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-11 03:11:38 UTC (rev 169)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/init.rb 2007-05-11 10:42:53 UTC (rev 170)
@@ -2,8 +2,6 @@
# Copyright:: Copyright (c) 2007 Future Architect Inc.
# Licence:: MIT Licence
-require 'ap4r/stored_message'
-require 'async_helper'
require 'ap4r_client'
class ActionController::Base
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-11 03:11:38 UTC (rev 169)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-11 10:42:53 UTC (rev 170)
@@ -3,6 +3,7 @@
# Licence:: MIT Licence
require 'forwardable'
+require 'async_helper'
module Ap4r
class Client
@@ -17,5 +18,10 @@
alias :async_to :async_dispatch
alias :transaction :transaction_with_saf
+
+ def message
+ @message ||= {}
+ end
+
end
end
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-11 03:11:38 UTC (rev 169)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-11 10:42:53 UTC (rev 170)
@@ -3,6 +3,8 @@
# Licence:: MIT Licence
require 'reliable-msg'
+require 'ap4r/stored_message'
+require 'message_builder'
module Ap4r
@@ -128,10 +130,11 @@
queue_name, queue_message, queue_headers = __before_block_evaluation(url_options, async_params, rm_options)
if block_given?
- yield
+ message_builder = ::Ap4r::MessageBuilder.new(queue_name, queue_message, queue_headers)
+ yield message_builder
+ #TODO __after_block_evaluation, merge message_builder to queue_*, 2007/5/11 kato-k
end
-
if Thread.current[:use_saf]
stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers)
Added: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb (rev 0)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-11 10:42:53 UTC (rev 170)
@@ -0,0 +1,31 @@
+# Author:: Kiwamu Kato
+# Copyright:: Copyright (c) 2007 Future Architect Inc.
+# Licence:: MIT Licence
+
+module Ap4r
+ class MessageBuilder
+
+ def initialize(queue_name, queue_message, queue_headers)
+ @queue_name = queue_name
+ @queue_message = queue_message
+ @queue_headers = queue_headers
+ end
+
+ attr_accessor :queue_name, :queue_message, :queue_headers
+
+ def method_missing name, *args
+ if name.to_s == "[]="
+ @queue_message[args[0]] = args[1]
+ elsif name.to_s == "headers"
+ return @queue_headers
+ elsif name.to_s == "http_headers"
+ #TODO implementation, 2007/5/11 kato-k
+ return {}
+ else
+ # remove "="
+ @queue_message[name.to_s.chop] = args[0]
+ end
+ end
+
+ end
+end
From kato-k at rubyforge.org Mon May 14 01:27:47 2007
From: kato-k at rubyforge.org (kato-k at rubyforge.org)
Date: Mon, 14 May 2007 01:27:47 -0400 (EDT)
Subject: [ap4r-devel] [171] trunk/samples/HelloWorld: Refactoring: extract
method and add comments.
Message-ID: <20070514052748.4BB615240BC4@rubyforge.org>
Revision: 171
Author: kato-k
Date: 2007-05-14 01:27:42 -0400 (Mon, 14 May 2007)
Log Message:
-----------
Refactoring: extract method and add comments.
Modified Paths:
--------------
trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb
Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb
===================================================================
--- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-11 10:42:53 UTC (rev 170)
+++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-14 05:27:42 UTC (rev 171)
@@ -19,10 +19,11 @@
def execute_with_block
write('Hello')
- #TODO: change first argument like the following sample, 2007/5/10 kato-k
- # ap4r.async_to(:url => {:contoroller => 'foo', :action => 'bar'}, ...)
+ # TODO: should change first argument like the following sample, 2007/5/10 kato-k
+ # e.g.
+ # ap4r.async_to(:url => {:contoroller => 'foo', :action => 'bar'}, ...)
#
- #TODO: support more flexible description in block, 2007/5/10 kato-k
+ # TODO: should support more flexible description in a block, 2007/5/10 kato-k
ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do |b|
# message body
@@ -30,18 +31,18 @@
b.hoge1 = "hoge1"
b[:hoge2] = "hoge2"
- #b.hoge3 "hoge3" # not support
+ b.hoge3 "hoge3" # this pattern is possible, but unrecommend
b.id = 1 # method "id" is also available.
- #TODO support ActiveRecord object, 2007/5/11 kato-k
+ # TODO: should support ActiveRecord object, 2007/5/11 kato-k
b.order = @order #?
# message header
- b.headers[:target_url] = "http://..."
+ b.headers[:target_url] = "http://localhost:3000/async_world/execute_via_http"
b.headers[:priority] = 2
- b.headers[:druby_url] = "druby://..."
+ b.headers[:druby_url] = "druby://:6438"
- #TODO support http headers, 2007/5/11 kato-k
+ # TODO: should support http headers, 2007/5/11 kato-k
#b.http_headers[:accept] = "text/plain"
#b.http_headers["content-type"] = "application/json"
#b.headers[:http_header_accept] = "text/plain"
@@ -53,12 +54,12 @@
req[:_array] = [0, 1, 2]
- #TODO support various request formats such as xml and json, 2007/5/11 kato-k
+ # TODO: should support various request formats such as xml and json, 2007/5/11 kato-k
#b.queue_message = @order, :include => :details, :format => :json
#b.queue_message = @order, :include => :details, :format => :xml
- # contens of message are referable
+ # contents of message are referable
p b.queue_name
p b.queue_message
p b.queue_headers
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-11 10:42:53 UTC (rev 170)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-14 05:27:42 UTC (rev 171)
@@ -13,19 +13,27 @@
attr_accessor :queue_name, :queue_message, :queue_headers
- def method_missing name, *args
- if name.to_s == "[]="
+ # +Ap4r::Client#async_to+ method has block argument and message header and body and so on
+ # are defined in a block.
+ # This +method_missing+ is for picking up defined parameters in a block..
+ def method_missing(method_name, *args)
+ if method_name == :[]=
@queue_message[args[0]] = args[1]
- elsif name.to_s == "headers"
+ elsif method_name == :headers
return @queue_headers
- elsif name.to_s == "http_headers"
+ elsif method_name == :http_headers
#TODO implementation, 2007/5/11 kato-k
return {}
else
- # remove "="
- @queue_message[name.to_s.chop] = args[0]
+ @queue_message[remove_equal_mark_from(method_name)] = args[0]
end
end
+ private
+ def remove_equal_mark_from symbol
+ return symbol unless /=$/ =~ symbol.to_s
+ return symbol.to_s.chop.to_sym
+ end
+
end
end
From kato-k at rubyforge.org Mon May 14 02:15:44 2007
From: kato-k at rubyforge.org (kato-k at rubyforge.org)
Date: Mon, 14 May 2007 02:15:44 -0400 (EDT)
Subject: [ap4r-devel] [172]
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib: Implemented
merge logic after yield proccessing.
Message-ID: <20070514061544.BCD775240BD0@rubyforge.org>
Revision: 172
Author: kato-k
Date: 2007-05-14 02:15:44 -0400 (Mon, 14 May 2007)
Log Message:
-----------
Implemented merge logic after yield proccessing.
Modified Paths:
--------------
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-14 05:27:42 UTC (rev 171)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-14 06:15:44 UTC (rev 172)
@@ -127,12 +127,38 @@
#
def async_dispatch(url_options = {}, async_params = nil, rm_options = nil, &block)
- queue_name, queue_message, queue_headers = __before_block_evaluation(url_options, async_params, rm_options)
+ # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino
+ if logger.debug?
+ logger.debug("url_options: ")
+ logger.debug(url_options.inspect)
+ logger.debug("async_params: ")
+ logger.debug(async_params.inspect)
+ logger.debug("rm_options: ")
+ logger.debug(rm_options.inspect)
+ end
+ # TODO: clone it, 2006/10/16 shino
+ url_options ||= {}
+ url_options[:controller] ||= self.controller_path.gsub("/", ".")
+ rm_options = @@default_rm_options.merge(rm_options || {})
+
+ # Only async_params is not cloned. options and rm_options are cloned before now.
+ # This is a current contract between this class and converter classes.
+ converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self)
+ logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"}
+
+ queue_name = __get_queue_name(url_options, rm_options)
+ queue_message = converter.make_params
+ queue_headers = converter.make_rm_options
+
if block_given?
message_builder = ::Ap4r::MessageBuilder.new(queue_name, queue_message, queue_headers)
+
yield message_builder
- #TODO __after_block_evaluation, merge message_builder to queue_*, 2007/5/11 kato-k
+
+ queue_name = message_builder.queue_name
+ queue_message = queue_message.merge(message_builder.queue_message)
+ queue_headers = queue_headers.merge(message_builder.queue_headers)
end
if Thread.current[:use_saf]
@@ -152,30 +178,6 @@
end
private
- def __before_block_evaluation(url_options, async_params, rm_options)
- # TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino
- if logger.debug?
- logger.debug("url_options: ")
- logger.debug(url_options.inspect)
- logger.debug("async_params: ")
- logger.debug(async_params.inspect)
- logger.debug("rm_options: ")
- logger.debug(rm_options.inspect)
- end
-
- # TODO: clone it, 2006/10/16 shino
- url_options ||= {}
- url_options[:controller] ||= self.controller_path.gsub("/", ".")
- rm_options = @@default_rm_options.merge(rm_options || {})
-
- # Only async_params is not cloned. options and rm_options are cloned before now.
- # This is a current contract between this class and converter classes.
- converter = Converters[rm_options[:dispatch_mode]].new(url_options, async_params, rm_options, self)
- logger.debug{"druby uri for queue-manager : #{DRUBY_URI}"}
-
- return __get_queue_name(url_options, rm_options), converter.make_params, converter.make_rm_options
- end
-
def __queue_put(queue_name, queue_message, queue_headers)
# TODO: can use a Queue instance repeatedly? 2007/05/02 by shino
q = ReliableMsg::Queue.new(queue_name, :drb_uri => DRUBY_URI)
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-14 05:27:42 UTC (rev 171)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-14 06:15:44 UTC (rev 172)
@@ -3,6 +3,9 @@
# Licence:: MIT Licence
module Ap4r
+
+ # This class has +method_missing+.
+ # Scope of application should be limited ?
class MessageBuilder
def initialize(queue_name, queue_message, queue_headers)
From shino at rubyforge.org Thu May 17 01:39:43 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 17 May 2007 01:39:43 -0400 (EDT)
Subject: [ap4r-devel] [173] trunk/ap4r/test/unit/dispatcher_base_spec.rb:
Add a spec file for Ap4r::Dispatchers::Base#modify_message.
Message-ID: <20070517053943.4C4B85240B1E@rubyforge.org>
Revision: 173
Author: shino
Date: 2007-05-17 01:39:41 -0400 (Thu, 17 May 2007)
Log Message:
-----------
Add a spec file for Ap4r::Dispatchers::Base#modify_message.
Now it has rather trivial specs only.
RSpec is 0.9.4 in my gem repository.
Added Paths:
-----------
trunk/ap4r/test/unit/dispatcher_base_spec.rb
Added: trunk/ap4r/test/unit/dispatcher_base_spec.rb
===================================================================
--- trunk/ap4r/test/unit/dispatcher_base_spec.rb (rev 0)
+++ trunk/ap4r/test/unit/dispatcher_base_spec.rb 2007-05-17 05:39:41 UTC (rev 173)
@@ -0,0 +1,25 @@
+require File.join(File.dirname(__FILE__), "../test_helper")
+
+require "reliable-msg"
+require "ap4r/dispatcher"
+
+describe "Ap4r::Dispatchers::Base message modification with no configuration" do
+ before(:each) do
+ @headers = {:target_url => "http://www.sample.org:8888/aaa/bbb" }
+ @body = "body"
+ @message = ReliableMsg::Message.new(1, @headers.clone, @body.clone)
+ @conf = {}
+ @dispatcher = Ap4r::Dispatchers::Base.new(:message, @conf)
+ @dispatcher.modify_message
+ end
+
+ it "should not change headers" do
+ @message.headers == @headers.should
+ end
+
+ it "should not change body" do
+ @message.object.should == @body
+ end
+
+
+end
From shino at rubyforge.org Thu May 17 02:09:16 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 17 May 2007 02:09:16 -0400 (EDT)
Subject: [ap4r-devel] [174] trunk/ap4r: add test helper file
Message-ID: <20070517060916.E182CA970002@rubyforge.org>
Revision: 174
Author: shino
Date: 2007-05-17 02:09:16 -0400 (Thu, 17 May 2007)
Log Message:
-----------
add test helper file
Modified Paths:
--------------
trunk/ap4r/Rakefile
Added Paths:
-----------
trunk/ap4r/test/test_helper.rb
Modified: trunk/ap4r/Rakefile
===================================================================
--- trunk/ap4r/Rakefile 2007-05-17 05:39:41 UTC (rev 173)
+++ trunk/ap4r/Rakefile 2007-05-17 06:09:16 UTC (rev 174)
@@ -94,6 +94,14 @@
rdoc.rdoc_files.include('rails_plugin/**/*.rb')
}
+# Test tasks ----------------------------------------------------------------
+require 'spec/rake/spectask'
+
+desc "Run unit specs"
+Spec::Rake::SpecTask.new('unit_specs') do |t|
+ t.spec_files = FileList['spec/unit/**/*.rb']
+end
+
# AP4R release ----------------------------------------------------------------
desc "Make gem"
Added: trunk/ap4r/test/test_helper.rb
===================================================================
--- trunk/ap4r/test/test_helper.rb (rev 0)
+++ trunk/ap4r/test/test_helper.rb 2007-05-17 06:09:16 UTC (rev 174)
@@ -0,0 +1 @@
+$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
From shino at rubyforge.org Thu May 17 02:13:18 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 17 May 2007 02:13:18 -0400 (EDT)
Subject: [ap4r-devel] [175] trunk/ap4r: change directory name,
"test" to "spec"
Message-ID: <20070517061318.17EAB5240AD3@rubyforge.org>
Revision: 175
Author: shino
Date: 2007-05-17 02:13:17 -0400 (Thu, 17 May 2007)
Log Message:
-----------
change directory name, "test" to "spec"
Added Paths:
-----------
trunk/ap4r/spec/
trunk/ap4r/spec/test_helper.rb
trunk/ap4r/spec/unit/
Removed Paths:
-------------
trunk/ap4r/spec/unit/
trunk/ap4r/test/
Copied: trunk/ap4r/spec (from rev 172, trunk/ap4r/test)
Copied: trunk/ap4r/spec/test_helper.rb (from rev 174, trunk/ap4r/test/test_helper.rb)
===================================================================
--- trunk/ap4r/spec/test_helper.rb (rev 0)
+++ trunk/ap4r/spec/test_helper.rb 2007-05-17 06:13:17 UTC (rev 175)
@@ -0,0 +1 @@
+$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
Copied: trunk/ap4r/spec/unit (from rev 174, trunk/ap4r/test/unit)
From shino at rubyforge.org Thu May 17 02:13:55 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 17 May 2007 02:13:55 -0400 (EDT)
Subject: [ap4r-devel] [176] trunk/ap4r/spec: change file name,
"test_helper" to "spec_helper"
Message-ID: <20070517061355.580855240AD3@rubyforge.org>
Revision: 176
Author: shino
Date: 2007-05-17 02:13:54 -0400 (Thu, 17 May 2007)
Log Message:
-----------
change file name, "test_helper" to "spec_helper"
Added Paths:
-----------
trunk/ap4r/spec/spec_helper.rb
Removed Paths:
-------------
trunk/ap4r/spec/test_helper.rb
Copied: trunk/ap4r/spec/spec_helper.rb (from rev 175, trunk/ap4r/spec/test_helper.rb)
===================================================================
--- trunk/ap4r/spec/spec_helper.rb (rev 0)
+++ trunk/ap4r/spec/spec_helper.rb 2007-05-17 06:13:54 UTC (rev 176)
@@ -0,0 +1 @@
+$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
Deleted: trunk/ap4r/spec/test_helper.rb
===================================================================
--- trunk/ap4r/spec/test_helper.rb 2007-05-17 06:13:17 UTC (rev 175)
+++ trunk/ap4r/spec/test_helper.rb 2007-05-17 06:13:54 UTC (rev 176)
@@ -1 +0,0 @@
-$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
From shino at rubyforge.org Thu May 17 02:18:20 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 17 May 2007 02:18:20 -0400 (EDT)
Subject: [ap4r-devel] [177] trunk/ap4r/spec: change direcotry name,
"unit" to "local".
Message-ID: <20070517061820.605DC5240B21@rubyforge.org>
Revision: 177
Author: shino
Date: 2007-05-17 02:18:19 -0400 (Thu, 17 May 2007)
Log Message:
-----------
change direcotry name, "unit" to "local".
I intend specs in this dir run in one process.
And other sibling dirs like "with_reliable_msg" or "with_rails", etc. will be born.
Added Paths:
-----------
trunk/ap4r/spec/local/
Removed Paths:
-------------
trunk/ap4r/spec/unit/
Copied: trunk/ap4r/spec/local (from rev 175, trunk/ap4r/spec/unit)
From shino at rubyforge.org Thu May 17 02:20:01 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 17 May 2007 02:20:01 -0400 (EDT)
Subject: [ap4r-devel] [178] trunk/ap4r/spec/local/dispatcher_base_spec.rb:
modification associated with renaming.
Message-ID: <20070517062001.8F48B5240AD3@rubyforge.org>
Revision: 178
Author: shino
Date: 2007-05-17 02:20:01 -0400 (Thu, 17 May 2007)
Log Message:
-----------
modification associated with renaming.
Modified Paths:
--------------
trunk/ap4r/spec/local/dispatcher_base_spec.rb
Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb
===================================================================
--- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 06:18:19 UTC (rev 177)
+++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 06:20:01 UTC (rev 178)
@@ -1,4 +1,4 @@
-require File.join(File.dirname(__FILE__), "../test_helper")
+require File.join(File.dirname(__FILE__), "../spec_helper")
require "reliable-msg"
require "ap4r/dispatcher"
From shino at rubyforge.org Thu May 17 02:22:58 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 17 May 2007 02:22:58 -0400 (EDT)
Subject: [ap4r-devel] [179] trunk/ap4r/Rakefile: made rake task for specs on
local
Message-ID: <20070517062258.343B35240ACC@rubyforge.org>
Revision: 179
Author: shino
Date: 2007-05-17 02:22:57 -0400 (Thu, 17 May 2007)
Log Message:
-----------
made rake task for specs on local
Modified Paths:
--------------
trunk/ap4r/Rakefile
Modified: trunk/ap4r/Rakefile
===================================================================
--- trunk/ap4r/Rakefile 2007-05-17 06:20:01 UTC (rev 178)
+++ trunk/ap4r/Rakefile 2007-05-17 06:22:57 UTC (rev 179)
@@ -98,8 +98,10 @@
require 'spec/rake/spectask'
desc "Run unit specs"
-Spec::Rake::SpecTask.new('unit_specs') do |t|
- t.spec_files = FileList['spec/unit/**/*.rb']
+namespace :spec do
+ Spec::Rake::SpecTask.new(:local) do |t|
+ t.spec_files = FileList['spec/local/**/*.rb']
+ end
end
# AP4R release ----------------------------------------------------------------
From shino at rubyforge.org Thu May 17 03:53:31 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 17 May 2007 03:53:31 -0400 (EDT)
Subject: [ap4r-devel] [180] trunk/ap4r: add some specs associated with url
rewrite
Message-ID: <20070517075331.4A6525240A96@rubyforge.org>
Revision: 180
Author: shino
Date: 2007-05-17 03:53:30 -0400 (Thu, 17 May 2007)
Log Message:
-----------
add some specs associated with url rewrite
Modified Paths:
--------------
trunk/ap4r/Rakefile
trunk/ap4r/spec/local/dispatcher_base_spec.rb
Modified: trunk/ap4r/Rakefile
===================================================================
--- trunk/ap4r/Rakefile 2007-05-17 06:22:57 UTC (rev 179)
+++ trunk/ap4r/Rakefile 2007-05-17 07:53:30 UTC (rev 180)
@@ -97,8 +97,8 @@
# Test tasks ----------------------------------------------------------------
require 'spec/rake/spectask'
-desc "Run unit specs"
namespace :spec do
+ desc "Run specs running in only one process"
Spec::Rake::SpecTask.new(:local) do |t|
t.spec_files = FileList['spec/local/**/*.rb']
end
Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb
===================================================================
--- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 06:22:57 UTC (rev 179)
+++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 07:53:30 UTC (rev 180)
@@ -3,13 +3,13 @@
require "reliable-msg"
require "ap4r/dispatcher"
-describe "Ap4r::Dispatchers::Base message modification with no configuration" do
+describe Ap4r::Dispatchers::Base, " message modification with no configuration" do
before(:each) do
@headers = {:target_url => "http://www.sample.org:8888/aaa/bbb" }
@body = "body"
@message = ReliableMsg::Message.new(1, @headers.clone, @body.clone)
@conf = {}
- @dispatcher = Ap4r::Dispatchers::Base.new(:message, @conf)
+ @dispatcher = Ap4r::Dispatchers::Base.new(@message, @conf)
@dispatcher.modify_message
end
@@ -21,5 +21,29 @@
@message.object.should == @body
end
-
end
+
+describe Ap4r::Dispatchers::Base, " message modification with url rewrite" do
+ before(:each) do
+ @headers = {:target_url => "http://www.sample.org:8888/aaa/bbb" }
+ @body = "body"
+ @message = ReliableMsg::Message.new(1, @headers.clone, @body.clone)
+ @conf = {"modify_rules" => {"url" => "proc{|url| url.port = url.port + 11}" }}
+ @dispatcher = Ap4r::Dispatchers::Base.new(@message, @conf)
+ @dispatcher.modify_message
+ end
+
+ it "should not change headers except :target_url" do
+ @message.headers[:target_url] = @headers[:target_url]
+ @message.headers.should == @headers
+ end
+
+ it "should change :target_url as ruled" do
+ @message.headers[:target_url].should == "http://www.sample.org:8899/aaa/bbb"
+ end
+
+ it "should not change body" do
+ @message.object.should == @body
+ end
+
+end
From shino at rubyforge.org Thu May 17 03:54:22 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 17 May 2007 03:54:22 -0400 (EDT)
Subject: [ap4r-devel] [181] trunk/ap4r/ap4r-devel-test.txt: remove a file to
test ap4r-devel mailing list
Message-ID: <20070517075422.229D25240A96@rubyforge.org>
Revision: 181
Author: shino
Date: 2007-05-17 03:54:21 -0400 (Thu, 17 May 2007)
Log Message:
-----------
remove a file to test ap4r-devel mailing list
Removed Paths:
-------------
trunk/ap4r/ap4r-devel-test.txt
Deleted: trunk/ap4r/ap4r-devel-test.txt
===================================================================
--- trunk/ap4r/ap4r-devel-test.txt 2007-05-17 07:53:30 UTC (rev 180)
+++ trunk/ap4r/ap4r-devel-test.txt 2007-05-17 07:54:21 UTC (rev 181)
@@ -1,3 +0,0 @@
-test
-test2
-test3
From shino at rubyforge.org Thu May 17 05:22:02 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Thu, 17 May 2007 05:22:02 -0400 (EDT)
Subject: [ap4r-devel] [182] trunk/ap4r: add specs of validations of response
Message-ID: <20070517092202.DFFE55240846@rubyforge.org>
Revision: 182
Author: shino
Date: 2007-05-17 05:22:01 -0400 (Thu, 17 May 2007)
Log Message:
-----------
add specs of validations of response
Modified Paths:
--------------
trunk/ap4r/lib/ap4r/dispatcher.rb
trunk/ap4r/spec/local/dispatcher_base_spec.rb
Modified: trunk/ap4r/lib/ap4r/dispatcher.rb
===================================================================
--- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-17 07:54:21 UTC (rev 181)
+++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-17 09:22:01 UTC (rev 182)
@@ -133,7 +133,7 @@
# is mandatory and others are optional (no operations by default).
# * +modify_message+ to preprocess a message, e.g. rewirte URL or discard message.
# * +invoke+ to execute main logic, e.g. HTTP POST call. *mandatory*
- # * +varidate_response+ to judge whether +invoke+ finished successfully.
+ # * +validate_response+ to judge whether +invoke+ finished successfully.
# * +response+ to return the result of +invoke+ process.
class Base
@@ -154,7 +154,7 @@
self.modify_message
logger.debug{"Ap4r::Dispatcher after modification\n#{@message.to_yaml}"}
self.invoke
- self.varidate_response
+ self.validate_response
self.response
end
@@ -169,7 +169,7 @@
raise 'must be implemented in subclasses'
end
- def varidate_response
+ def validate_response
# nop
end
@@ -212,15 +212,15 @@
@message.object)
end
- def varidate_response
+ def validate_response
logger.debug{"response status [#{@response.code} #{@response.message}]"}
- varidate_response_status(Net::HTTPOK)
- varidate_response_body(/true/)
+ validate_response_status(Net::HTTPOK)
+ validate_response_body(/true/)
end
# Checks whether the response status is a kind of +status_kind+.
# +status_kind+ should be one of Net::HTTPRespose's subclasses.
- def varidate_response_status(status_kind)
+ def validate_response_status(status_kind)
#TODO: make the difinition of success variable, 2006/10/13 shino
unless @response.kind_of?(status_kind)
error_message = "HTTP Response FAILURE, " +
@@ -234,7 +234,7 @@
# Checks whether the response body includes +pattern+.
# +pattern+ should be a regular expression.
- def varidate_response_body(pattern)
+ def validate_response_body(pattern)
unless @response.body =~ pattern
error_message = "HTTP Response FAILURE, status" +
" [#{@response.code} #{@response.message}], body [#{@response.body}]"
@@ -257,7 +257,7 @@
@success, @response = client.call2(@message[:target_action], @message.object)
end
- def varidate_response
+ def validate_response
raise @response unless @success
end
end
Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb
===================================================================
--- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 07:54:21 UTC (rev 181)
+++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 09:22:01 UTC (rev 182)
@@ -3,6 +3,14 @@
require "reliable-msg"
require "ap4r/dispatcher"
+class Ap4r::ResponseMock
+ attr_accessor :body
+end
+
+class Ap4r::Dispatchers::Base
+ attr_accessor :response
+end
+
describe Ap4r::Dispatchers::Base, " message modification with no configuration" do
before(:each) do
@headers = {:target_url => "http://www.sample.org:8888/aaa/bbb" }
@@ -47,3 +55,58 @@
end
end
+
+describe Ap4r::Dispatchers::Http, " validation of response status" do
+ before(:each) do
+ @message = nil
+ @conf = nil
+ @dispatcher = Ap4r::Dispatchers::Http.new(@message, @conf)
+ end
+
+ it "should accept 200 status" do
+ @dispatcher.response = Net::HTTPOK.new(nil, 200, nil)
+ proc{ @dispatcher.validate_response_status(Net::HTTPOK) }.should_not raise_error
+ end
+
+ it "should repel 201 status" do
+ @dispatcher.response = Net::HTTPCreated.new(nil, 201, nil)
+ proc{ @dispatcher.validate_response_status(Net::HTTPOK) }.should raise_error
+ end
+
+ it "should repel 301 status" do
+ @dispatcher.response = Net::HTTPMovedPermanently.new(nil, 301, nil)
+ proc{ @dispatcher.validate_response_status(Net::HTTPOK) }.should raise_error
+ end
+
+end
+
+describe Ap4r::Dispatchers::Http, " validation of response body" do
+ before(:each) do
+ @message = nil
+ @conf = nil
+ @dispatcher = Ap4r::Dispatchers::Http.new(@message, @conf)
+ @response = Ap4r::ResponseMock.new
+ @dispatcher.response = @response
+ end
+
+ it 'should accept just text "true"' do
+ @response.body = "true"
+ proc{ @dispatcher.validate_response_body(/true/) }.should_not raise_error
+ end
+
+ it 'should accept text including "true"' do
+ @response.body = "first line is not important\nsome words true and more\nand also third line is useless."
+ proc{ @dispatcher.validate_response_body(/true/) }.should_not raise_error
+ end
+
+ it 'should repel empty text' do
+ @response.body = ""
+ proc{ @dispatcher.validate_response_body(/true/) }.should raise_error
+ end
+
+ it 'should repel long text without "true"' do
+ @response.body = "first line is not important\nsome words, more and more\nand also third line is useless."
+ proc{ @dispatcher.validate_response_body(/true/) }.should raise_error
+ end
+
+end
From shino at rubyforge.org Fri May 18 01:47:57 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Fri, 18 May 2007 01:47:57 -0400 (EDT)
Subject: [ap4r-devel] [183] trunk/ap4r/spec/local/dispatcher_base_spec.rb:
test spec failure
Message-ID: <20070518054757.396DB5240B5E@rubyforge.org>
Revision: 183
Author: shino
Date: 2007-05-18 01:47:56 -0400 (Fri, 18 May 2007)
Log Message:
-----------
test spec failure
Modified Paths:
--------------
trunk/ap4r/spec/local/dispatcher_base_spec.rb
Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb
===================================================================
--- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-17 09:22:01 UTC (rev 182)
+++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-18 05:47:56 UTC (rev 183)
@@ -110,3 +110,9 @@
end
end
+
+describe "test for spec failuer" do
+ it "should fail" do
+ 1.should == 0
+ end
+end
From shino at rubyforge.org Fri May 18 02:23:28 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Fri, 18 May 2007 02:23:28 -0400 (EDT)
Subject: [ap4r-devel] [184] trunk/ap4r/spec/local/dispatcher_base_spec.rb:
remove a spec to emulate build failure
Message-ID: <20070518062328.4FD125240B6C@rubyforge.org>
Revision: 184
Author: shino
Date: 2007-05-18 02:23:27 -0400 (Fri, 18 May 2007)
Log Message:
-----------
remove a spec to emulate build failure
Modified Paths:
--------------
trunk/ap4r/spec/local/dispatcher_base_spec.rb
Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb
===================================================================
--- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-18 05:47:56 UTC (rev 183)
+++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-18 06:23:27 UTC (rev 184)
@@ -110,9 +110,3 @@
end
end
-
-describe "test for spec failuer" do
- it "should fail" do
- 1.should == 0
- end
-end
From kato-k at rubyforge.org Fri May 18 06:16:19 2007
From: kato-k at rubyforge.org (kato-k at rubyforge.org)
Date: Fri, 18 May 2007 06:16:19 -0400 (EDT)
Subject: [ap4r-devel] [185] trunk: Support block argument for async_to
method.\n Support ActiveRecord object for async parameter.
Message-ID: <20070518101619.2A6545240AB4@rubyforge.org>
Revision: 185
Author: kato-k
Date: 2007-05-18 06:16:17 -0400 (Fri, 18 May 2007)
Log Message:
-----------
Support block argument for async_to method.\n Support ActiveRecord object for async parameter. \n Support xml over http protocol.
Modified Paths:
--------------
trunk/ap4r/lib/ap4r/dispatcher.rb
trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb
Modified: trunk/ap4r/lib/ap4r/dispatcher.rb
===================================================================
--- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-18 06:23:27 UTC (rev 184)
+++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-18 10:16:17 UTC (rev 185)
@@ -208,10 +208,25 @@
# TODO: should be added some request headers 2006/10/12 shino
# e.g. X-Ap4r-Version, Accept(need it?)
# TODO: Now supports POST only, 2006/10/12 shino
- @response = Net::HTTP.post_form(URI.parse(@message[:target_url]),
- @message.object)
+ @response = nil
+ uri = URI.parse(@message[:target_url])
+ headers = make_header
+
+ Net::HTTP.start(uri.host, uri.port) do |http|
+ @response, = http.post(uri.path, @message.object, headers)
+ end
end
+ def make_header
+ headers = { }
+ @message.headers.map do |k,v|
+ s = StringScanner.new(k.to_s)
+ s.scan(/\Ahttp_header_/)
+ headers[s.post_match] = v if s.post_match
+ end
+ headers
+ end
+
def validate_response
logger.debug{"response status [#{@response.code} #{@response.message}]"}
validate_response_status(Net::HTTPOK)
Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb
===================================================================
--- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-18 06:23:27 UTC (rev 184)
+++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-18 10:16:17 UTC (rev 185)
@@ -19,51 +19,32 @@
def execute_with_block
write('Hello')
- # TODO: should change first argument like the following sample, 2007/5/10 kato-k
- # e.g.
- # ap4r.async_to(:url => {:contoroller => 'foo', :action => 'bar'}, ...)
- #
- # TODO: should support more flexible description in a block, 2007/5/10 kato-k
- ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req = {} ) do |b|
+ ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}) do
- # message body
- # basically, use block argumennt
- b.hoge1 = "hoge1"
- b[:hoge2] = "hoge2"
+ # basic
+ #body :hoge, "hoge"
+ #header :priority, 2
- b.hoge3 "hoge3" # this pattern is possible, but unrecommend
- b.id = 1 # method "id" is also available.
+ # AR object
+ #body :sm, Ap4r::StoredMessage.find(:first), :except => :id
- # TODO: should support ActiveRecord object, 2007/5/11 kato-k
- b.order = @order #?
+ # by xml/http
+ body :hoge, "hoge"
+ body :sm, Ap4r::StoredMessage.find(:first), :except => :id
+ format :xml
- # message header
- b.headers[:target_url] = "http://localhost:3000/async_world/execute_via_http"
- b.headers[:priority] = 2
- b.headers[:druby_url] = "druby://:6438"
+ # ..or explicit setting for http header
+ #body :hoge, "hoge"
+ #body :sm, Ap4r::StoredMessage.find(:first), :except => :id
+ #http_header "Content-type", "application/x-xml"
- # TODO: should support http headers, 2007/5/11 kato-k
- #b.http_headers[:accept] = "text/plain"
- #b.http_headers["content-type"] = "application/json"
- #b.headers[:http_header_accept] = "text/plain"
+ # directly dealing with xml message
+ #body_as_xml Ap4r::StoredMessage.find(:first).to_xml(:except => :id)
- #tricky pattern, but definition in method arguments is necessary.
- req[:_num] = rand(100)
- req[:_str] = "World"
- req[:_hash] = {:a => 1, :b => 2}
- req[:_array] = [0, 1, 2]
-
-
- # TODO: should support various request formats such as xml and json, 2007/5/11 kato-k
- #b.queue_message = @order, :include => :details, :format => :json
- #b.queue_message = @order, :include => :details, :format => :xml
-
-
- # contents of message are referable
- p b.queue_name
- p b.queue_message
- p b.queue_headers
-
+ # TODO: referable, but should change longer and unique name?, 2007/5/17 kato-k
+ # p @queue_name
+ # p @queue_message
+ # p @queue_headers
end
render :nothing => true
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-18 06:23:27 UTC (rev 184)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-18 10:16:17 UTC (rev 185)
@@ -19,9 +19,5 @@
alias :async_to :async_dispatch
alias :transaction :transaction_with_saf
- def message
- @message ||= {}
- end
-
end
end
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-18 06:23:27 UTC (rev 184)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-18 10:16:17 UTC (rev 185)
@@ -125,7 +125,7 @@
# Object of argumemts (async_params, options and rm_options) will not be modified.
# Implementors (of this class and converters) should not modify them.
#
- def async_dispatch(url_options = {}, async_params = nil, rm_options = nil, &block)
+ def async_dispatch(url_options = {}, async_params = {}, rm_options = {}, &block)
# TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino
if logger.debug?
@@ -151,30 +151,28 @@
queue_message = converter.make_params
queue_headers = converter.make_rm_options
+ message_builder = ::Ap4r::MessageBuilder.new(queue_name, queue_message, queue_headers)
if block_given?
- message_builder = ::Ap4r::MessageBuilder.new(queue_name, queue_message, queue_headers)
-
- yield message_builder
-
- queue_name = message_builder.queue_name
- queue_message = queue_message.merge(message_builder.queue_message)
- queue_headers = queue_headers.merge(message_builder.queue_headers)
+ message_builder.instance_eval(&block)
end
+ queue_name = message_builder.queue_name
+ formatted_queue_message = message_builder.format_queue_message
+ queue_headers = message_builder.queue_headers
if Thread.current[:use_saf]
- stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers)
+ stored_message = ::Ap4r::StoredMessage.store(queue_name, formatted_queue_message, queue_headers)
Thread.current[:stored_messages].store(
stored_message.id,
{
- :queue_message => queue_message,
+ :queue_message => formatted_queue_message,
:queue_name => queue_name,
:queue_headers => queue_headers
} )
return stored_message.id
end
- __queue_put(queue_name, queue_message, queue_headers)
+ __queue_put(queue_name, formatted_queue_message, queue_headers)
end
private
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-18 06:23:27 UTC (rev 184)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-18 10:16:17 UTC (rev 185)
@@ -2,41 +2,112 @@
# Copyright:: Copyright (c) 2007 Future Architect Inc.
# Licence:: MIT Licence
+require 'active_record'
+
module Ap4r
- # This class has +method_missing+.
- # Scope of application should be limited ?
class MessageBuilder
def initialize(queue_name, queue_message, queue_headers)
@queue_name = queue_name
@queue_message = queue_message
@queue_headers = queue_headers
+ @format = :urlencode
+ @xml_encoded_body = nil
+ @to_xml_options = {:root => "root"}
end
attr_accessor :queue_name, :queue_message, :queue_headers
+ attr_reader :xml_encoded_body, :format, :to_xml_options
- # +Ap4r::Client#async_to+ method has block argument and message header and body and so on
- # are defined in a block.
- # This +method_missing+ is for picking up defined parameters in a block..
- def method_missing(method_name, *args)
- if method_name == :[]=
- @queue_message[args[0]] = args[1]
- elsif method_name == :headers
- return @queue_headers
- elsif method_name == :http_headers
- #TODO implementation, 2007/5/11 kato-k
- return {}
+ def body(k, v, options = { })
+ k ||= v.class
+ if v.kind_of? ActiveRecord::Base
+ @queue_message[k.to_sym] = v.attributes
+ @to_xml_options = @to_xml_options.merge(options)
else
- @queue_message[remove_equal_mark_from(method_name)] = args[0]
+ @queue_message[k.to_sym] = v
end
+
end
+ def body_as_xml(xml_message)
+ @xml_encoded_body = xml_message
+ end
+
+ def body_as_text(text_message)
+ # TODO: implementation
+ end
+
+ def body_as_yaml(yaml_message)
+ # TODO: implementation
+ end
+
+ def body_as_json(json_message)
+ # TODO: implementation
+ end
+
+ def header(k, v)
+ @queue_headers[k.to_sym] = v
+ end
+
+ def http_header(k, v)
+ @queue_headers["http_header_#{k}".to_sym] = v
+ end
+
+ def format(v)
+ case @format = v
+ when :xml
+ http_header('Content-type', 'application/x-xml')
+ else
+ http_header('Content-type', 'application/x-www-form-urlencoded')
+ end
+ end
+
+ def format_queue_message
+ return @xml_encoded_body if @xml_encoded_body
+
+ case @format
+ when :xml
+ return @queue_message.to_xml @to_xml_options
+ else
+ return query_string(@queue_message)
+ end
+ end
+
+ def query_string(hash)
+ build_query_string(hash, nil, nil)
+ end
+
private
- def remove_equal_mark_from symbol
- return symbol unless /=$/ =~ symbol.to_s
- return symbol.to_s.chop.to_sym
+ def build_query_string(hash, query = nil, top = nil)
+ query ||= []
+ top ||= ""
+
+ _top = top.dup
+
+ hash.each do |k,v|
+ top = _top
+ top += top == "" ? "#{urlencode(k.to_s)}" : "[#{urlencode(k.to_s)}]"
+ if v.kind_of? Hash
+ build_query_string(v, query, top)
+ elsif v.kind_of? Array
+ v.each do |e|
+ query << "#{top}[]=#{urlencode(e.to_s)}"
+ end
+ else
+ query << "#{top}=#{urlencode(v.to_s)}"
+ end
+ end
+ query.join('&')
end
+ def simple_url_encoded_form_data params, sep = '&'
+ params.map {|k,v| "#{urlencode(k.to_s)}=#{urlencode(v.to_s)}" }.join(sep)
+ end
+
+ def urlencode(str)
+ str.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0]) }
+ end
end
end
From shino at rubyforge.org Mon May 21 01:01:43 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Mon, 21 May 2007 01:01:43 -0400 (EDT)
Subject: [ap4r-devel] [186] trunk/ap4r/spec/local/dispatcher_base_spec.rb:
Fix typo.
Message-ID: <20070521050143.D18695240C9B@rubyforge.org>
Revision: 186
Author: shino
Date: 2007-05-21 01:01:43 -0400 (Mon, 21 May 2007)
Log Message:
-----------
Fix typo. Mock is NOT stub
Modified Paths:
--------------
trunk/ap4r/spec/local/dispatcher_base_spec.rb
Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb
===================================================================
--- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-18 10:16:17 UTC (rev 185)
+++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-21 05:01:43 UTC (rev 186)
@@ -3,7 +3,7 @@
require "reliable-msg"
require "ap4r/dispatcher"
-class Ap4r::ResponseMock
+class Ap4r::ResponseStub
attr_accessor :body
end
@@ -85,7 +85,7 @@
@message = nil
@conf = nil
@dispatcher = Ap4r::Dispatchers::Http.new(@message, @conf)
- @response = Ap4r::ResponseMock.new
+ @response = Ap4r::ResponseStub.new
@dispatcher.response = @response
end
From shino at rubyforge.org Mon May 21 02:16:22 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Mon, 21 May 2007 02:16:22 -0400 (EDT)
Subject: [ap4r-devel] [187] trunk/ap4r/Rakefile: add rake task to execute
RSpec with Rcov
Message-ID: <20070521061622.B93085240C9D@rubyforge.org>
Revision: 187
Author: shino
Date: 2007-05-21 02:16:21 -0400 (Mon, 21 May 2007)
Log Message:
-----------
add rake task to execute RSpec with Rcov
Modified Paths:
--------------
trunk/ap4r/Rakefile
Modified: trunk/ap4r/Rakefile
===================================================================
--- trunk/ap4r/Rakefile 2007-05-21 05:01:43 UTC (rev 186)
+++ trunk/ap4r/Rakefile 2007-05-21 06:16:21 UTC (rev 187)
@@ -94,13 +94,28 @@
rdoc.rdoc_files.include('rails_plugin/**/*.rb')
}
-# Test tasks ----------------------------------------------------------------
+# Spec tasks ----------------------------------------------------------------
require 'spec/rake/spectask'
namespace :spec do
- desc "Run specs running in only one process"
- Spec::Rake::SpecTask.new(:local) do |t|
- t.spec_files = FileList['spec/local/**/*.rb']
+ %w(local).each do |flavor|
+ desc "Run #{flavor} examples"
+ Spec::Rake::SpecTask.new(flavor) do |t|
+ t.spec_files = FileList["spec/#{flavor}/**/*.rb"]
+ end
+
+ namespace :coverage do
+ desc "Run #{flavor} examples with RCov"
+ Spec::Rake::SpecTask.new(flavor) do |t|
+ t.spec_files = FileList["spec/#{flavor}/**/*.rb"]
+ t.rcov = true
+ excludes = %w(^spec\/)
+ if ENV['GEM_HOME']
+ excludes << Regexp.escape(ENV['GEM_HOME'])
+ end
+ t.rcov_opts = ["--exclude" , excludes.join(",")]
+ end
+ end
end
end
From kato-k at rubyforge.org Mon May 21 04:58:08 2007
From: kato-k at rubyforge.org (kato-k at rubyforge.org)
Date: Mon, 21 May 2007 04:58:08 -0400 (EDT)
Subject: [ap4r-devel] [188] trunk/samples/HelloWorld/vendor/plugins/ap4r/lib:
Refactoring: changed meshods name and add comments.
Message-ID: <20070521085808.62AD652409B4@rubyforge.org>
Revision: 188
Author: kato-k
Date: 2007-05-21 04:58:07 -0400 (Mon, 21 May 2007)
Log Message:
-----------
Refactoring: changed meshods name and add comments.
Modified Paths:
--------------
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-21 06:16:21 UTC (rev 187)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-21 08:58:07 UTC (rev 188)
@@ -156,23 +156,23 @@
message_builder.instance_eval(&block)
end
queue_name = message_builder.queue_name
- formatted_queue_message = message_builder.format_queue_message
- queue_headers = message_builder.queue_headers
+ queue_message = message_builder.format_message_body
+ queue_headers = message_builder.message_headers
if Thread.current[:use_saf]
- stored_message = ::Ap4r::StoredMessage.store(queue_name, formatted_queue_message, queue_headers)
+ stored_message = ::Ap4r::StoredMessage.store(queue_name, queue_message, queue_headers)
Thread.current[:stored_messages].store(
stored_message.id,
{
- :queue_message => formatted_queue_message,
+ :queue_message => queue_message,
:queue_name => queue_name,
:queue_headers => queue_headers
} )
return stored_message.id
end
- __queue_put(queue_name, formatted_queue_message, queue_headers)
+ __queue_put(queue_name, queue_message, queue_headers)
end
private
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-21 06:16:21 UTC (rev 187)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/message_builder.rb 2007-05-21 08:58:07 UTC (rev 188)
@@ -6,72 +6,99 @@
module Ap4r
+ # This +MessageBuilder+ is the class for formatting message body.
+ # Current support formats are text, xml, json and yaml,
+ # and the formatted messages are sent over HTTP.
+ #
+ # Using +format+ method, this class automatically changes the format of
+ # the given message body and adds appropriate +Content-type+ to http header.
+ # Or using +body_as_*+ methods, you can directly assign formatted message body.
class MessageBuilder
def initialize(queue_name, queue_message, queue_headers)
@queue_name = queue_name
- @queue_message = queue_message
- @queue_headers = queue_headers
- @format = :urlencode
- @xml_encoded_body = nil
+ @message_body = queue_message
+ @message_headers = queue_headers
+ @format = nil
+ @message_body_with_format = nil
@to_xml_options = {:root => "root"}
end
- attr_accessor :queue_name, :queue_message, :queue_headers
- attr_reader :xml_encoded_body, :format, :to_xml_options
+ attr_accessor :queue_name, :message_body, :message_headers
+ attr_reader :format, :to_xml_options
def body(k, v, options = { })
k ||= v.class
if v.kind_of? ActiveRecord::Base
- @queue_message[k.to_sym] = v.attributes
+ @message_body[k.to_sym] = v
@to_xml_options = @to_xml_options.merge(options)
else
- @queue_message[k.to_sym] = v
+ @message_body[k.to_sym] = v
end
-
end
- def body_as_xml(xml_message)
- @xml_encoded_body = xml_message
+ def header(k, v)
+ @message_headers[k.to_sym] = v
end
- def body_as_text(text_message)
- # TODO: implementation
+ def http_header(k, v)
+ @message_headers["http_header_#{k}".to_sym] = v
end
- def body_as_yaml(yaml_message)
- # TODO: implementation
+ def format(v)
+ case @format = v
+ when :text
+ set_content_type("text/plain")
+ when :xml
+ set_content_type("text/xml application/x-xml")
+ when :json
+ set_content_type("application/json")
+ when :yaml
+ set_content_type("text/plain text/yaml")
+ else
+ set_content_type("application/x-www-form-urlencoded")
+ end
end
- def body_as_json(json_message)
- # TODO: implementation
+ def body_as_text(text)
+ @message_body_with_format = text
+ format :text
end
- def header(k, v)
- @queue_headers[k.to_sym] = v
+ def body_as_xml(xml)
+ @message_body_with_format = xml
+ format :xml
end
- def http_header(k, v)
- @queue_headers["http_header_#{k}".to_sym] = v
+ def body_as_json(json)
+ @message_body_with_format = json
+ format :json
end
- def format(v)
- case @format = v
- when :xml
- http_header('Content-type', 'application/x-xml')
- else
- http_header('Content-type', 'application/x-www-form-urlencoded')
- end
+ def body_as_yaml(yaml)
+ @message_body_with_format = yaml
+ format :yaml
end
- def format_queue_message
- return @xml_encoded_body if @xml_encoded_body
+ def format_message_body
+ return @message_body_with_format if @message_body_with_format
case @format
+ when :text
+ return @message_budy.to_s
when :xml
- return @queue_message.to_xml @to_xml_options
+ return @message_body.to_xml @to_xml_options
+ when :json
+ return @message_body.to_json
+ when :yaml
+ return @message_body.to_yaml
else
- return query_string(@queue_message)
+ @message_body.each do |k,v|
+ if v.kind_of? ActiveRecord::Base
+ @message_body[k] = v.attributes
+ end
+ end
+ return query_string(@message_body)
end
end
@@ -102,12 +129,16 @@
query.join('&')
end
- def simple_url_encoded_form_data params, sep = '&'
+ def simple_url_encoded_form_data(params, sep = '&')
params.map {|k,v| "#{urlencode(k.to_s)}=#{urlencode(v.to_s)}" }.join(sep)
end
def urlencode(str)
str.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0]) }
end
+
+ def set_content_type(type)
+ http_header("Content-type", type)
+ end
end
end
From shino at rubyforge.org Tue May 22 03:25:38 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Tue, 22 May 2007 03:25:38 -0400 (EDT)
Subject: [ap4r-devel] [189] trunk/ap4r: add code statistics task
Message-ID: <20070522072538.B87F85240CB3@rubyforge.org>
Revision: 189
Author: shino
Date: 2007-05-22 03:25:38 -0400 (Tue, 22 May 2007)
Log Message:
-----------
add code statistics task
Modified Paths:
--------------
trunk/ap4r/Rakefile
Removed Paths:
-------------
trunk/ap4r/lib/ap4r/util/loc.rb
Modified: trunk/ap4r/Rakefile
===================================================================
--- trunk/ap4r/Rakefile 2007-05-21 08:58:07 UTC (rev 188)
+++ trunk/ap4r/Rakefile 2007-05-22 07:25:38 UTC (rev 189)
@@ -113,7 +113,8 @@
if ENV['GEM_HOME']
excludes << Regexp.escape(ENV['GEM_HOME'])
end
- t.rcov_opts = ["--exclude" , excludes.join(",")]
+ t.rcov_opts = ["--exclude" , excludes.join(","),
+ "--text-summary"]
end
end
end
@@ -182,3 +183,18 @@
}
end
+# AP4R misc tools ----------------------------------------------------------------
+
+desc "display code statistics"
+task :stats do
+ require 'rubygems'
+ require 'active_support'
+ require 'code_statistics'
+ CodeStatistics::TEST_TYPES.concat(["Local specs"])
+ CodeStatistics.new(
+ ["Core Sources", "lib"],
+ ["Rails plugin", "rails_plugin"],
+ ["Scripts", "script"],
+ ["Local specs", "spec/local"]
+ ).to_s
+end
Deleted: trunk/ap4r/lib/ap4r/util/loc.rb
===================================================================
--- trunk/ap4r/lib/ap4r/util/loc.rb 2007-05-21 08:58:07 UTC (rev 188)
+++ trunk/ap4r/lib/ap4r/util/loc.rb 2007-05-22 07:25:38 UTC (rev 189)
@@ -1,13 +0,0 @@
-# Author:: Shunichi Shinohara
-# Copyright:: Copyright (c) 2007 Future Architect Inc.
-# Licence:: MIT Licence
-
-require 'rubygems'
-require 'active_support'
-require 'code_statistics'
-
-CodeStatistics.new(
- ["Core Sources", "lib"],
- ["Rails plugin", "rails_plugin"],
- ["Scripts", "script"]
-).to_s
From shino at rubyforge.org Tue May 22 04:25:47 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Tue, 22 May 2007 04:25:47 -0400 (EDT)
Subject: [ap4r-devel] [190] trunk/ap4r/spec/local/dispatcher_base_spec.rb:
refactoring: change stub into mock provided by RSpec
Message-ID: <20070522082548.395B55240CB5@rubyforge.org>
Revision: 190
Author: shino
Date: 2007-05-22 04:25:46 -0400 (Tue, 22 May 2007)
Log Message:
-----------
refactoring: change stub into mock provided by RSpec
Modified Paths:
--------------
trunk/ap4r/spec/local/dispatcher_base_spec.rb
Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb
===================================================================
--- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-22 07:25:38 UTC (rev 189)
+++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-22 08:25:46 UTC (rev 190)
@@ -3,10 +3,6 @@
require "reliable-msg"
require "ap4r/dispatcher"
-class Ap4r::ResponseStub
- attr_accessor :body
-end
-
class Ap4r::Dispatchers::Base
attr_accessor :response
end
@@ -85,27 +81,29 @@
@message = nil
@conf = nil
@dispatcher = Ap4r::Dispatchers::Http.new(@message, @conf)
- @response = Ap4r::ResponseStub.new
+ @response = mock("response")
@dispatcher.response = @response
end
it 'should accept just text "true"' do
- @response.body = "true"
+ @response.should_receive(:body).once.and_return("true")
proc{ @dispatcher.validate_response_body(/true/) }.should_not raise_error
end
it 'should accept text including "true"' do
- @response.body = "first line is not important\nsome words true and more\nand also third line is useless."
+ @response.should_receive(:body).and_return{
+ "first line is not important\nsome words true and more\nand also third line is useless." }
proc{ @dispatcher.validate_response_body(/true/) }.should_not raise_error
end
it 'should repel empty text' do
- @response.body = ""
+ @response.should_receive(:body).and_return("")
proc{ @dispatcher.validate_response_body(/true/) }.should raise_error
end
it 'should repel long text without "true"' do
- @response.body = "first line is not important\nsome words, more and more\nand also third line is useless."
+ @response.should_receive(:body).and_return{
+ "first line is not important\nsome words, more and more\nand also third line is useless." }
proc{ @dispatcher.validate_response_body(/true/) }.should raise_error
end
From kato-k at rubyforge.org Tue May 22 04:40:55 2007
From: kato-k at rubyforge.org (kato-k at rubyforge.org)
Date: Tue, 22 May 2007 04:40:55 -0400 (EDT)
Subject: [ap4r-devel] [191]
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib: Added
comments about api usage.
Message-ID: <20070522084055.2F9FE5240957@rubyforge.org>
Revision: 191
Author: kato-k
Date: 2007-05-22 04:40:54 -0400 (Tue, 22 May 2007)
Log Message:
-----------
Added comments about api usage.
Modified Paths:
--------------
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb
trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-22 08:25:46 UTC (rev 190)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-05-22 08:40:54 UTC (rev 191)
@@ -16,7 +16,10 @@
def_delegators :@controller, :logger, :url_for
+ # Alias for ::Ap4r::AsyncHelper::Base.async_dispatch
alias :async_to :async_dispatch
+
+ # Alias for ::Ap4r::AsyncHelper::Base.transaction_with_saf
alias :transaction :transaction_with_saf
end
Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb
===================================================================
--- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-22 08:25:46 UTC (rev 190)
+++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-22 08:40:54 UTC (rev 191)
@@ -125,6 +125,58 @@
# Object of argumemts (async_params, options and rm_options) will not be modified.
# Implementors (of this class and converters) should not modify them.
#
+ # Examples: the most simple
+ #
+ # async_dispatch({:controller => 'next_controller', :action => 'next_action'},
+ # {:world_id => 1, :message => "World"})
+ #
+ #
+ # Examples: taking block
+ #
+ # async_dispatch({:controller => 'next_controller', :action => 'next_action'}) do
+ # body :world_id, 1
+ # body :message, "World"
+ # end
+ #
+ #
+ # Examples: transmitting ActiveRecord object
+ #
+ # async_dispatch({:controller => 'next_controller', :action => 'next_action'}) do
+ # body :world, World.find(1)
+ # body :message, "World"
+ # end
+ #
+ #
+ # Examples: transmitting with xml format over http (now support text, json and yaml format).
+ #
+ # async_dispatch({:controller => 'next_controller', :action => 'next_action'}) do
+ # body :world, World.find(1)
+ # body :message, "World"
+ # format :xml
+ # end
+ #
+ #
+ # Examples: direct assignment for formatted message body
+ #
+ # async_dispatch({:controller => 'next_controller', :action => 'next_action'}) do
+ # world = World.find(1).to_xml :except => ...
+ # body_as_xml world
+ # end
+ #
+ #
+ # Examples: setting message header
+ #
+ # async_dispatch({:controller => 'next_controller', :action => 'next_action'}) do
+ # body :world_id, 1
+ # body :message, "World"
+ #
+ # header :priority, 1
+ # http_header "Content-type", ...
+ # end
+ #
+ #
+ # This method is aliased as ::Ap4r::Client#async_to
+ #
def async_dispatch(url_options = {}, async_params = {}, rm_options = {}, &block)
# TODO: add :url to url_options to specify :target_url shortly 2007/05/02 by shino
From shino at rubyforge.org Tue May 22 05:03:30 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Tue, 22 May 2007 05:03:30 -0400 (EDT)
Subject: [ap4r-devel] [192] trunk/ap4r/spec/local/dispatcher_base_spec.rb:
add specs as validation of HTTP response status
Message-ID: <20070522090330.32FB75240990@rubyforge.org>
Revision: 192
Author: shino
Date: 2007-05-22 05:03:29 -0400 (Tue, 22 May 2007)
Log Message:
-----------
add specs as validation of HTTP response status
Modified Paths:
--------------
trunk/ap4r/spec/local/dispatcher_base_spec.rb
Modified: trunk/ap4r/spec/local/dispatcher_base_spec.rb
===================================================================
--- trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-22 08:40:54 UTC (rev 191)
+++ trunk/ap4r/spec/local/dispatcher_base_spec.rb 2007-05-22 09:03:29 UTC (rev 192)
@@ -52,11 +52,9 @@
end
-describe Ap4r::Dispatchers::Http, " validation of response status" do
+describe Ap4r::Dispatchers::Http, " validation of response status as HTTP OK" do
before(:each) do
- @message = nil
- @conf = nil
- @dispatcher = Ap4r::Dispatchers::Http.new(@message, @conf)
+ @dispatcher = Ap4r::Dispatchers::Http.new(@message = nil, @conf = nil)
end
it "should accept 200 status" do
@@ -76,6 +74,28 @@
end
+describe Ap4r::Dispatchers::Http, " validation of response status as 2xx" do
+ before(:each) do
+ @dispatcher = Ap4r::Dispatchers::Http.new(@message = nil, @conf = nil)
+ end
+
+ it "should accept 200 status" do
+ @dispatcher.response = Net::HTTPOK.new(nil, 200, nil)
+ proc{ @dispatcher.validate_response_status(Net::HTTPSuccess) }.should_not raise_error
+ end
+
+ it "should accept 201 status" do
+ @dispatcher.response = Net::HTTPCreated.new(nil, 201, nil)
+ proc{ @dispatcher.validate_response_status(Net::HTTPSuccess) }.should_not raise_error
+ end
+
+ it "should repel 301 status" do
+ @dispatcher.response = Net::HTTPMovedPermanently.new(nil, 301, nil)
+ proc{ @dispatcher.validate_response_status(Net::HTTPSuccess) }.should raise_error
+ end
+
+end
+
describe Ap4r::Dispatchers::Http, " validation of response body" do
before(:each) do
@message = nil
From shino at rubyforge.org Tue May 22 05:14:18 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Tue, 22 May 2007 05:14:18 -0400 (EDT)
Subject: [ap4r-devel] [193] trunk/ap4r/spec/spec_helper.rb: add stub logic
for coverage report
Message-ID: <20070522091418.B87BD524097B@rubyforge.org>
Revision: 193
Author: shino
Date: 2007-05-22 05:14:18 -0400 (Tue, 22 May 2007)
Log Message:
-----------
add stub logic for coverage report
Modified Paths:
--------------
trunk/ap4r/spec/spec_helper.rb
Modified: trunk/ap4r/spec/spec_helper.rb
===================================================================
--- trunk/ap4r/spec/spec_helper.rb 2007-05-22 09:03:29 UTC (rev 192)
+++ trunk/ap4r/spec/spec_helper.rb 2007-05-22 09:14:18 UTC (rev 193)
@@ -1 +1,7 @@
$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
+
+# TODO: stub logic to take files with no specs in coverage report 2007/05/22 by shino
+%w(carrier message_store_ext multi_queue
+ queue_manager_ext store_and_forward).each{|f|
+ require "ap4r/#{f}"
+}
From shino at rubyforge.org Mon May 28 04:55:51 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Mon, 28 May 2007 04:55:51 -0400 (EDT)
Subject: [ap4r-devel] [194] trunk/ap4r/lib/ap4r/dispatcher.rb: make sleep
interval to class variable (ad-hoc)
Message-ID: <20070528085551.71E0D5240AC4@rubyforge.org>
Revision: 194
Author: shino
Date: 2007-05-28 04:55:50 -0400 (Mon, 28 May 2007)
Log Message:
-----------
make sleep interval to class variable (ad-hoc)
Modified Paths:
--------------
trunk/ap4r/lib/ap4r/dispatcher.rb
Modified: trunk/ap4r/lib/ap4r/dispatcher.rb
===================================================================
--- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-22 09:14:18 UTC (rev 193)
+++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-28 08:55:50 UTC (rev 194)
@@ -21,6 +21,8 @@
# - calls a Dispatchers::Base's instance.
class Dispatchers
+ @@sleep_inverval = 0.1
+
@@logger = nil
def self.logger
@@logger
@@ -102,7 +104,7 @@
logger.info{ "start dispatcher: targets= #{mq}, index= #{index})" }
until Thread.current[:dying]
# TODO: change sleep interval depending on last result? 2007/05/09 by shino
- sleep 0.1
+ sleep @@sleep_inverval
# logger.debug{ "try dispatch #{mq} #{mq.name}" }
# TODO: needs timeout?, 2006/10/16 shino
begin
From shino at rubyforge.org Mon May 28 04:56:46 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Mon, 28 May 2007 04:56:46 -0400 (EDT)
Subject: [ap4r-devel] [195] trunk/ap4r/lib/ap4r/mongrel.rb: remove warning
message, because it's noisy
Message-ID: <20070528085646.2FDA65240AEB@rubyforge.org>
Revision: 195
Author: shino
Date: 2007-05-28 04:56:45 -0400 (Mon, 28 May 2007)
Log Message:
-----------
remove warning message, because it's noisy
Modified Paths:
--------------
trunk/ap4r/lib/ap4r/mongrel.rb
Modified: trunk/ap4r/lib/ap4r/mongrel.rb
===================================================================
--- trunk/ap4r/lib/ap4r/mongrel.rb 2007-05-28 08:55:50 UTC (rev 194)
+++ trunk/ap4r/lib/ap4r/mongrel.rb 2007-05-28 08:56:45 UTC (rev 195)
@@ -47,7 +47,6 @@
# TODO not yet implemented 2007/04/09 by shino
#
class Ap4rHandler < ::Mongrel::HttpHandler
- STDERR.puts "CAUTION! This script is rather experimental."
attr_reader :files
@@file_only_methods = ["GET","HEAD"]
From shino at rubyforge.org Mon May 28 05:04:07 2007
From: shino at rubyforge.org (shino at rubyforge.org)
Date: Mon, 28 May 2007 05:04:07 -0400 (EDT)
Subject: [ap4r-devel] [196] trunk/samples/HelloWorld: second trial to make
rails integration test with ap4r
Message-ID: <20070528090407.355265240A9C@rubyforge.org>
Revision: 196
Author: shino
Date: 2007-05-28 05:04:06 -0400 (Mon, 28 May 2007)
Log Message:
-----------
second trial to make rails integration test with ap4r
Added Paths:
-----------
trunk/samples/HelloWorld/config/ap4r.yml.sample
trunk/samples/HelloWorld/test/ap4r_test_helper.rb
trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb
Added: trunk/samples/HelloWorld/config/ap4r.yml.sample
===================================================================
--- trunk/samples/HelloWorld/config/ap4r.yml.sample (rev 0)
+++ trunk/samples/HelloWorld/config/ap4r.yml.sample 2007-05-28 09:04:06 UTC (rev 196)
@@ -0,0 +1,10 @@
+---
+# need development? or production?
+# or consider proper structure for these
+development:
+
+test:
+ root_dir: ~/work/ap4r_project
+ config_file: config/queues_disk.cfg
+
+production:
Added: trunk/samples/HelloWorld/test/ap4r_test_helper.rb
===================================================================
--- trunk/samples/HelloWorld/test/ap4r_test_helper.rb (rev 0)
+++ trunk/samples/HelloWorld/test/ap4r_test_helper.rb 2007-05-28 09:04:06 UTC (rev 196)
@@ -0,0 +1,81 @@
+# Author:: Shunichi Shinohara
+# Copyright:: Copyright (c) 2007 Future Architect Inc.
+# Licence:: MIT Licence
+
+require 'erb'
+require 'yaml'
+require 'reliable-msg'
+require 'ap4r'
+
+class Ap4rTestHelper
+
+ def initialize(config_file = RAILS_ROOT + "/config/ap4r.yml")
+ raise "please create config/ap4r.yml to configure ap4r service." unless File.exist?(config_file)
+
+ config = {}
+ File.open(config_file, "r") do |input|
+ YAML.load_documents(ERB.new(input.read).result) do |doc|
+ config.merge! doc
+ end
+ end
+ @test_config = config["test"]
+ @root_dir = @test_config["root_dir"]
+ @config_file = @test_config["config_file"]
+ @test_server_config = ReliableMsg::Config.new(File.join(@root_dir, @config_file))
+ raise "config file #{@test_server_config.path} NOT exist!" unless @test_server_config.exist?
+ @test_server_config.load_no_create
+ end
+
+ # Starts ap4r service.
+ def start_service(wait_until_started = true)
+
+ command = "ruby #{@test_config["start_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " +
+ "start -d -c #{@root_dir} -A #{@config_file}"
+ print "executing command: #{command} ..."
+ system(command)
+ puts
+
+ @qm = DRbObject.new