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_with_uri("druby://localhost:#{@test_server_config.drb["port"]}") + # TODO: need to wait until ap4r has really started 2007/05/28 by shino + puts "ap4r service has started" + end + + # Stops ap4r service. + def stop_service + command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " + + "stop -c #{@root_dir}" + print "executing command: #{command} ..." + system(command) + puts + + @qm = nil + puts "ap4r service has stopped" + end + + def clear(*queues) + queues.each do |queue| + q = ReliableMsg::Queue.new(queue) + loop do + break unless q.get + end + end + end +end + +ap4r_test_helper = Ap4rTestHelper.new + +at_exit { + ap4r_test_helper.stop_service() +} + +ap4r_test_helper.start_service() + +class ActionController::IntegrationTest + cattr_accessor :ap4r_helper + + def ap4r_helper + @@ap4r_helper + end +end + +ActionController::IntegrationTest.ap4r_helper = ap4r_test_helper Added: trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb (rev 0) +++ trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb 2007-05-28 09:04:06 UTC (rev 196) @@ -0,0 +1,15 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require "#{File.dirname(__FILE__)}/../test_helper" +require "#{File.dirname(__FILE__)}/../ap4r_test_helper" + +class HelloRailsIntegrationWithAp4rTest < ActionController::IntegrationTest + + # Trivial test case to test the ap4r test helper. + def test_truth + assert true + assert_not_nil ap4r_helper() + end +end From shino at rubyforge.org Mon May 28 22:17:34 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 28 May 2007 22:17:34 -0400 (EDT) Subject: [ap4r-devel] [197] trunk/samples/HelloWorld/test/integration: make directories for trials for testing with AP4R Message-ID: <20070529021734.618A55240B97@rubyforge.org> Revision: 197 Author: shino Date: 2007-05-28 22:17:33 -0400 (Mon, 28 May 2007) Log Message: ----------- make directories for trials for testing with AP4R Modified Paths: -------------- trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb Added Paths: ----------- trunk/samples/HelloWorld/test/integration/just_inside_integration_test/ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb Removed Paths: ------------- trunk/samples/HelloWorld/test/integration/hello_world_stories_test.rb Modified: trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb 2007-05-28 09:04:06 UTC (rev 196) +++ trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb 2007-05-29 02:17:33 UTC (rev 197) @@ -3,13 +3,27 @@ # Licence:: MIT Licence require "#{File.dirname(__FILE__)}/../test_helper" -require "#{File.dirname(__FILE__)}/../ap4r_test_helper" +# require "#{File.dirname(__FILE__)}/../ap4r_test_helper" +require "#{File.dirname(__FILE__)}/../ap4r_queue_stub" +# TODO: transactional fixtures vs. multiple http calls? 2007/05/29 by shino class HelloRailsIntegrationWithAp4rTest < ActionController::IntegrationTest # Trivial test case to test the ap4r test helper. def test_truth assert true - assert_not_nil ap4r_helper() + assert_not_nil ap4r_helper end + + def test_hello_via_http_and_async + puts '===== test start =====' + get "/sync_hello/execute_via_http" + puts '===== test end =====' + assert_equal 200, status + puts '===== assert end =====' + assert_equal 1, @controller.ap4r.async_messages.size + sleep 1 + puts '===== sleep 10 end =====' + end + end Deleted: trunk/samples/HelloWorld/test/integration/hello_world_stories_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/hello_world_stories_test.rb 2007-05-28 09:04:06 UTC (rev 196) +++ trunk/samples/HelloWorld/test/integration/hello_world_stories_test.rb 2007-05-29 02:17:33 UTC (rev 197) @@ -1,104 +0,0 @@ -require "#{File.dirname(__FILE__)}/../test_helper" - -require 'net/http' - -# Trial implementation of test cases with ap4r integration. -# some comments: -# - Subclassing IntegrationTest is adequate? -# - Clearance of data in a database and queues should be included. -# - AP4R server can be running in process? -# - dispatcher control is needed for split assertions between (a)sync logics. -# - Workspaces of ap4r and rails should have some conventions for convinience. -# - Think about transition to RSpec. -# -class HelloWorldStoriesTest < ActionController::IntegrationTest - - def test_start_ap4r_server - with_services do - assert_one_line_added do - say_hello(:with => :http) - end - assert_one_line_added do - join_async_world - end - end - end - - private - - # Starts rails service and ap4r service. - # After block execution, stops both. - def with_services - begin - start_rails_service - begin - start_ap4r_service - sleep 1 # make sure - yield - ensure - stop_ap4r_service - end - ensure - stop_rails_service - end - end - - # Starts ap4r service. - # Uses script at script/mongrel_ap4r. - def start_ap4r_service - system("ruby script/mongrel_ap4r start -d -A config/queues_disk.cfg") - puts "ap4r service has started" - end - - # Stops ap4r service. - def stop_ap4r_service - system("ruby script/mongrel_ap4r stop") - puts "ap4r service has stopped" - end - - # Starts rails service. - # Invokes mongrel_rails, so mongrel_rails should be installed. - def start_rails_service - system("mongrel_rails start -d --environment test") - puts "rails service has started" - end - - # Stops rails service. - def stop_rails_service - system("mongrel_rails stop") - puts "rails service has stopped" - end - - # Requests to sync_hello/execute_via_*. - # Implemented by using net/http, not by +post+ method of rails integration test. - # There's plenty of scope for refinement. - def say_hello(options) - options[:via] ||= :http - Net::HTTP.start("localhost", 3000) do |http| - http.request_post("/sync_hello/execute_via_#{options[:via].to_s.downcase}", - "sleep=1") - end - end - - # Waits for async logic to finish. - # Not what-is-called join, but just sleep. - def join_async_world - sleep 2 - end - - # returns line count of HelloWorld.txt file - def line_count - `wc -l public/HelloWorld.txt`.to_i - end - - def assert_lines_added(initial, delta) - assert_equal (initial + delta), line_count - end - - def assert_one_line_added - initial = line_count - yield - assert_lines_added(initial, 1) - end - -end Copied: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb (from rev 193, trunk/samples/HelloWorld/test/integration/hello_world_stories_test.rb) =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb (rev 0) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-29 02:17:33 UTC (rev 197) @@ -0,0 +1,104 @@ +require "#{File.dirname(__FILE__)}/../test_helper" + +require 'net/http' + +# Trial implementation of test cases with ap4r integration. +# some comments: +# - Subclassing IntegrationTest is adequate? +# - Clearance of data in a database and queues should be included. +# - AP4R server can be running in process? +# - dispatcher control is needed for split assertions between (a)sync logics. +# - Workspaces of ap4r and rails should have some conventions for convinience. +# - Think about transition to RSpec. +# +class HelloWorldStoriesTest < ActionController::IntegrationTest + + def test_start_ap4r_server + with_services do + assert_one_line_added do + say_hello(:with => :http) + end + assert_one_line_added do + join_async_world + end + end + end + + private + + # Starts rails service and ap4r service. + # After block execution, stops both. + def with_services + begin + start_rails_service + begin + start_ap4r_service + sleep 1 # make sure + yield + ensure + stop_ap4r_service + end + ensure + stop_rails_service + end + end + + # Starts ap4r service. + # Uses script at script/mongrel_ap4r. + def start_ap4r_service + system("ruby script/mongrel_ap4r start -d -A config/queues_disk.cfg") + puts "ap4r service has started" + end + + # Stops ap4r service. + def stop_ap4r_service + system("ruby script/mongrel_ap4r stop") + puts "ap4r service has stopped" + end + + # Starts rails service. + # Invokes mongrel_rails, so mongrel_rails should be installed. + def start_rails_service + system("mongrel_rails start -d --environment test") + puts "rails service has started" + end + + # Stops rails service. + def stop_rails_service + system("mongrel_rails stop") + puts "rails service has stopped" + end + + # Requests to sync_hello/execute_via_*. + # Implemented by using net/http, not by +post+ method of rails integration test. + # There's plenty of scope for refinement. + def say_hello(options) + options[:via] ||= :http + Net::HTTP.start("localhost", 3000) do |http| + http.request_post("/sync_hello/execute_via_#{options[:via].to_s.downcase}", + "sleep=1") + end + end + + # Waits for async logic to finish. + # Not what-is-called join, but just sleep. + def join_async_world + sleep 2 + end + + # returns line count of HelloWorld.txt file + def line_count + `wc -l public/HelloWorld.txt`.to_i + end + + def assert_lines_added(initial, delta) + assert_equal (initial + delta), line_count + end + + def assert_one_line_added + initial = line_count + yield + assert_lines_added(initial, 1) + end + +end From shino at rubyforge.org Mon May 28 22:19:20 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 28 May 2007 22:19:20 -0400 (EDT) Subject: [ap4r-devel] [198] trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/: one more directory for trail Message-ID: <20070529021920.561D75240B9C@rubyforge.org> Revision: 198 Author: shino Date: 2007-05-28 22:19:19 -0400 (Mon, 28 May 2007) Log Message: ----------- one more directory for trail Added Paths: ----------- trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/ From shino at rubyforge.org Mon May 28 22:20:36 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 28 May 2007 22:20:36 -0400 (EDT) Subject: [ap4r-devel] [199] trunk/samples/HelloWorld/test/integration: test support trial: just inside rails' integration test Message-ID: <20070529022036.D2F1AA970005@rubyforge.org> Revision: 199 Author: shino Date: 2007-05-28 22:20:35 -0400 (Mon, 28 May 2007) Log Message: ----------- test support trial: just inside rails' integration test Added Paths: ----------- trunk/samples/HelloWorld/test/integration/just_inside_integration_test/ap4r_queue_stub.rb trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb Removed Paths: ------------- trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb Deleted: trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb 2007-05-29 02:19:19 UTC (rev 198) +++ trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb 2007-05-29 02:20:35 UTC (rev 199) @@ -1,29 +0,0 @@ -# Author:: Shunichi Shinohara -# Copyright:: Copyright (c) 2007 Future Architect Inc. -# Licence:: MIT Licence - -require "#{File.dirname(__FILE__)}/../test_helper" -# require "#{File.dirname(__FILE__)}/../ap4r_test_helper" -require "#{File.dirname(__FILE__)}/../ap4r_queue_stub" - -# TODO: transactional fixtures vs. multiple http calls? 2007/05/29 by shino -class HelloRailsIntegrationWithAp4rTest < ActionController::IntegrationTest - - # Trivial test case to test the ap4r test helper. - def test_truth - assert true - assert_not_nil ap4r_helper - end - - def test_hello_via_http_and_async - puts '===== test start =====' - get "/sync_hello/execute_via_http" - puts '===== test end =====' - assert_equal 200, status - puts '===== assert end =====' - assert_equal 1, @controller.ap4r.async_messages.size - sleep 1 - puts '===== sleep 10 end =====' - end - -end Added: trunk/samples/HelloWorld/test/integration/just_inside_integration_test/ap4r_queue_stub.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/just_inside_integration_test/ap4r_queue_stub.rb (rev 0) +++ trunk/samples/HelloWorld/test/integration/just_inside_integration_test/ap4r_queue_stub.rb 2007-05-29 02:20:35 UTC (rev 199) @@ -0,0 +1,42 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'reliable-msg' +require 'ap4r' + +class Ap4rTestHelper + + def clear(*queues) + end +end + +ap4r_test_helper = Ap4rTestHelper.new + +class ActionController::IntegrationTest + cattr_accessor :ap4r_helper + + def ap4r_helper + @@ap4r_helper + end +end + +ActionController::IntegrationTest.ap4r_helper = ap4r_test_helper + +module Ap4r + module AsyncHelper + module Base + def async_messages + @messages ||= [] + end + + private + def __queue_put(queue_name, queue_message, queue_headers) + async_messages << + {:queue_name => queue_name, + :message => queue_message, + :queue_headers => queue_headers} + end + end + end +end Copied: trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb (from rev 197, trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb) =================================================================== --- trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb (rev 0) +++ trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb 2007-05-29 02:20:35 UTC (rev 199) @@ -0,0 +1,29 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require "#{File.dirname(__FILE__)}/../test_helper" +# require "#{File.dirname(__FILE__)}/../ap4r_test_helper" +require "#{File.dirname(__FILE__)}/../ap4r_queue_stub" + +# TODO: transactional fixtures vs. multiple http calls? 2007/05/29 by shino +class HelloRailsIntegrationWithAp4rTest < ActionController::IntegrationTest + + # Trivial test case to test the ap4r test helper. + def test_truth + assert true + assert_not_nil ap4r_helper + end + + def test_hello_via_http_and_async + puts '===== test start =====' + get "/sync_hello/execute_via_http" + puts '===== test end =====' + assert_equal 200, status + puts '===== assert end =====' + assert_equal 1, @controller.ap4r.async_messages.size + sleep 1 + puts '===== sleep 10 end =====' + end + +end From shino at rubyforge.org Mon May 28 22:22:53 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 28 May 2007 22:22:53 -0400 (EDT) Subject: [ap4r-devel] [200] trunk/samples/HelloWorld/test: test support trial: with ap4r server but without rails server Message-ID: <20070529022253.13B935240B97@rubyforge.org> Revision: 200 Author: shino Date: 2007-05-28 22:22:52 -0400 (Mon, 28 May 2007) Log Message: ----------- test support trial: with ap4r server but without rails server This case seems not promising. Added Paths: ----------- trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/ap4r_test_helper.rb trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/hello_rails_integration_with_ap4r_test.rb Removed Paths: ------------- trunk/samples/HelloWorld/test/ap4r_test_helper.rb Deleted: trunk/samples/HelloWorld/test/ap4r_test_helper.rb =================================================================== --- trunk/samples/HelloWorld/test/ap4r_test_helper.rb 2007-05-29 02:20:35 UTC (rev 199) +++ trunk/samples/HelloWorld/test/ap4r_test_helper.rb 2007-05-29 02:22:52 UTC (rev 200) @@ -1,81 +0,0 @@ -# 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_with_uri("druby://localhost:#{@test_server_config.drb["port"]}") - # TODO: need to wait until ap4r has really started 2007/05/28 by shino - puts "ap4r service has started" - end - - # Stops ap4r service. - def stop_service - command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " + - "stop -c #{@root_dir}" - print "executing command: #{command} ..." - system(command) - puts - - @qm = nil - puts "ap4r service has stopped" - end - - def clear(*queues) - queues.each do |queue| - q = ReliableMsg::Queue.new(queue) - loop do - break unless q.get - end - end - end -end - -ap4r_test_helper = Ap4rTestHelper.new - -at_exit { - ap4r_test_helper.stop_service() -} - -ap4r_test_helper.start_service() - -class ActionController::IntegrationTest - cattr_accessor :ap4r_helper - - def ap4r_helper - @@ap4r_helper - end -end - -ActionController::IntegrationTest.ap4r_helper = ap4r_test_helper Copied: trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/ap4r_test_helper.rb (from rev 196, trunk/samples/HelloWorld/test/ap4r_test_helper.rb) =================================================================== --- trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/ap4r_test_helper.rb (rev 0) +++ trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/ap4r_test_helper.rb 2007-05-29 02:22:52 UTC (rev 200) @@ -0,0 +1,110 @@ +# 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 + @qm = nil + 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 + + # TODO: need to wait until ap4r has really started 2007/05/28 by shino + loop do + begin + @qm = DRbObject.new_with_uri("druby://localhost:#{@test_server_config.drb["port"]}") + if @qm.alive? + puts "ap4r service has started" + break + end + rescue => e + sleep 0.5 + end + end + end + + # Stops ap4r service. + def stop_service + command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " + + "stop -c #{@root_dir}" + print "executing command: #{command} ..." + system(command) + puts + + @qm = nil + puts "ap4r service has stopped" + end + + def clear(*queues) + queues.each do |queue| + q = ReliableMsg::Queue.new(queue) + loop do + break unless q.get + end + end + end +end + +ap4r_test_helper = Ap4rTestHelper.new + +at_exit { + ap4r_test_helper.stop_service() +} + +ap4r_test_helper.start_service() + +class ActionController::IntegrationTest + cattr_accessor :ap4r_helper + + def ap4r_helper + @@ap4r_helper + end +end + +ActionController::IntegrationTest.ap4r_helper = ap4r_test_helper + +module Ap4r + module AsyncHelper + module Base + def async_messages + @messages ||= [] + end + + private + def __queue_put(queue_name, queue_message, queue_headers) + async_messages << + {:queue_name => queue_name, + :message => queue_message, + :queue_headers => queue_headers} + end + end + end +end Copied: trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/hello_rails_integration_with_ap4r_test.rb (from rev 199, trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb) =================================================================== --- trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/hello_rails_integration_with_ap4r_test.rb (rev 0) +++ trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/hello_rails_integration_with_ap4r_test.rb 2007-05-29 02:22:52 UTC (rev 200) @@ -0,0 +1,29 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require "#{File.dirname(__FILE__)}/../test_helper" +# require "#{File.dirname(__FILE__)}/../ap4r_test_helper" +require "#{File.dirname(__FILE__)}/../ap4r_queue_stub" + +# TODO: transactional fixtures vs. multiple http calls? 2007/05/29 by shino +class HelloRailsIntegrationWithAp4rTest < ActionController::IntegrationTest + + # Trivial test case to test the ap4r test helper. + def test_truth + assert true + assert_not_nil ap4r_helper + end + + def test_hello_via_http_and_async + puts '===== test start =====' + get "/sync_hello/execute_via_http" + puts '===== test end =====' + assert_equal 200, status + puts '===== assert end =====' + assert_equal 1, @controller.ap4r.async_messages.size + sleep 1 + puts '===== sleep 10 end =====' + end + +end From shino at rubyforge.org Mon May 28 22:29:54 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 28 May 2007 22:29:54 -0400 (EDT) Subject: [ap4r-devel] [201] trunk/samples/HelloWorld: Test support trial No.1 (summary): Message-ID: <20070529022954.3F1D05240B9C@rubyforge.org> Revision: 201 Author: shino Date: 2007-05-28 22:29:53 -0400 (Mon, 28 May 2007) Log Message: ----------- Test support trial No.1 (summary): Both with rails server(mongrel_rails) and ap4r server(mongral_ap4r). Simple line counting of the file "HelloWorld.txt" is tested. Some comments: - co-operation with transactional fixtures - AP4R root dir convention relative RAILS_ROOT - other comments are in test class's comment Modified Paths: -------------- trunk/samples/HelloWorld/app/controllers/async_world_controller.rb trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb Modified: trunk/samples/HelloWorld/app/controllers/async_world_controller.rb =================================================================== --- trunk/samples/HelloWorld/app/controllers/async_world_controller.rb 2007-05-29 02:22:52 UTC (rev 200) +++ trunk/samples/HelloWorld/app/controllers/async_world_controller.rb 2007-05-29 02:29:53 UTC (rev 201) @@ -26,6 +26,6 @@ def emulate_load(sleep_seconds = 10) sleep_seconds = 10 if sleep_seconds.blank? - sleep(sleep_seconds) + sleep(sleep_seconds.to_i) end end Modified: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-29 02:22:52 UTC (rev 200) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-29 02:29:53 UTC (rev 201) @@ -1,4 +1,4 @@ -require "#{File.dirname(__FILE__)}/../test_helper" +require "#{File.dirname(__FILE__)}/../../test_helper" require 'net/http' From shino at rubyforge.org Mon May 28 22:34:59 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 28 May 2007 22:34:59 -0400 (EDT) Subject: [ap4r-devel] [202] trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb: Test support trial No.2 (summary): Message-ID: <20070529023459.A5FF55240B9C@rubyforge.org> Revision: 202 Author: shino Date: 2007-05-28 22:34:59 -0400 (Mon, 28 May 2007) Log Message: ----------- Test support trial No.2 (summary): Both without rails server and without ap4r serve. Sync request response status (200) is only asserted so far. Some comments: - co-operation with transactional fixtures are straight forward, because neither AP4R calls nor HTTP calls (from dispatchers). - AP4R root dir convention relative RAILS_ROOT is still to be considered Modified Paths: -------------- trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb Modified: trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb 2007-05-29 02:29:53 UTC (rev 201) +++ trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb 2007-05-29 02:34:59 UTC (rev 202) @@ -2,11 +2,10 @@ # Copyright:: Copyright (c) 2007 Future Architect Inc. # Licence:: MIT Licence -require "#{File.dirname(__FILE__)}/../test_helper" -# require "#{File.dirname(__FILE__)}/../ap4r_test_helper" -require "#{File.dirname(__FILE__)}/../ap4r_queue_stub" +require "#{File.dirname(__FILE__)}/../../test_helper" +require "#{File.dirname(__FILE__)}/ap4r_queue_stub" -# TODO: transactional fixtures vs. multiple http calls? 2007/05/29 by shino +# TODO: not yet implemented async call invocations 2007/05/29 by shino class HelloRailsIntegrationWithAp4rTest < ActionController::IntegrationTest # Trivial test case to test the ap4r test helper. @@ -16,14 +15,9 @@ end def test_hello_via_http_and_async - puts '===== test start =====' get "/sync_hello/execute_via_http" - puts '===== test end =====' assert_equal 200, status - puts '===== assert end =====' assert_equal 1, @controller.ap4r.async_messages.size - sleep 1 - puts '===== sleep 10 end =====' end end From shino at rubyforge.org Mon May 28 22:40:39 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Mon, 28 May 2007 22:40:39 -0400 (EDT) Subject: [ap4r-devel] [203] trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/hello_rails_integration_with_ap4r_test.rb: Test support trial No.3 (summary): Message-ID: <20070529024039.DBC3D5240B9C@rubyforge.org> Revision: 203 Author: shino Date: 2007-05-28 22:40:32 -0400 (Mon, 28 May 2007) Log Message: ----------- Test support trial No.3 (summary): Without rails server, but with ap4r server(mongral_ap4r). No tests but being trival are implemented. Some comments: - co-operation with transactional fixtures are difficult. - This approach (not stubbing queueing, and no rails HTTP server) seems to be NOT promising. Modified Paths: -------------- trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/hello_rails_integration_with_ap4r_test.rb Modified: trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/hello_rails_integration_with_ap4r_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/hello_rails_integration_with_ap4r_test.rb 2007-05-29 02:34:59 UTC (rev 202) +++ trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/hello_rails_integration_with_ap4r_test.rb 2007-05-29 02:40:32 UTC (rev 203) @@ -2,9 +2,8 @@ # Copyright:: Copyright (c) 2007 Future Architect Inc. # Licence:: MIT Licence -require "#{File.dirname(__FILE__)}/../test_helper" -# require "#{File.dirname(__FILE__)}/../ap4r_test_helper" -require "#{File.dirname(__FILE__)}/../ap4r_queue_stub" +require "#{File.dirname(__FILE__)}/../../test_helper" +require "#{File.dirname(__FILE__)}/ap4r_test_helper" # TODO: transactional fixtures vs. multiple http calls? 2007/05/29 by shino class HelloRailsIntegrationWithAp4rTest < ActionController::IntegrationTest @@ -15,15 +14,11 @@ assert_not_nil ap4r_helper end - def test_hello_via_http_and_async - puts '===== test start =====' - get "/sync_hello/execute_via_http" - puts '===== test end =====' - assert_equal 200, status - puts '===== assert end =====' - assert_equal 1, @controller.ap4r.async_messages.size - sleep 1 - puts '===== sleep 10 end =====' - end + # error occurs on dispatcher's HTTP call, because of no rails server. +# def test_hello_via_http_and_async +# get "/sync_hello/execute_via_http" +# assert_equal 200, status +# assert_equal 1, @controller.ap4r.async_messages.size +# end end From shino at rubyforge.org Tue May 29 01:00:27 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 29 May 2007 01:00:27 -0400 (EDT) Subject: [ap4r-devel] [204] trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r: refactoring: separate helper codes from test case ones Message-ID: <20070529050029.A89885240C2E@rubyforge.org> Revision: 204 Author: shino Date: 2007-05-29 01:00:26 -0400 (Tue, 29 May 2007) Log Message: ----------- refactoring: separate helper codes from test case ones Modified Paths: -------------- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb Added Paths: ----------- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb Added: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb (rev 0) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-29 05:00:26 UTC (rev 204) @@ -0,0 +1,49 @@ +require "#{File.dirname(__FILE__)}/../../test_helper" + +class Test::Unit::TestCase + + # Starts rails service and ap4r service. + # After block execution, stops both. + def with_services + begin + start_rails_service + begin + start_ap4r_service + sleep 1 # make sure + yield + ensure + stop_ap4r_service + end + ensure + stop_rails_service + end + end + + # Starts ap4r service. + # Uses script at script/mongrel_ap4r. + def start_ap4r_service + system("ruby script/mongrel_ap4r start -d -A config/queues_disk.cfg") + puts "ap4r service has started" + end + + # Stops ap4r service. + def stop_ap4r_service + system("ruby script/mongrel_ap4r stop") + puts "ap4r service has stopped" + end + + # Starts rails service. + # Invokes mongrel_rails, so mongrel_rails should be installed. + def start_rails_service + system("mongrel_rails start -d --environment test") + puts "rails service has started" + end + + # Stops rails service. + def stop_rails_service + system("mongrel_rails stop") + puts "rails service has stopped" + end + +end + Modified: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-29 02:40:32 UTC (rev 203) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-29 05:00:26 UTC (rev 204) @@ -1,4 +1,4 @@ -require "#{File.dirname(__FILE__)}/../../test_helper" +require "#{File.dirname(__FILE__)}/ap4r_test_helper" require 'net/http' @@ -18,6 +18,7 @@ assert_one_line_added do say_hello(:with => :http) end + assert_one_line_added do join_async_world end @@ -26,49 +27,6 @@ private - # Starts rails service and ap4r service. - # After block execution, stops both. - def with_services - begin - start_rails_service - begin - start_ap4r_service - sleep 1 # make sure - yield - ensure - stop_ap4r_service - end - ensure - stop_rails_service - end - end - - # Starts ap4r service. - # Uses script at script/mongrel_ap4r. - def start_ap4r_service - system("ruby script/mongrel_ap4r start -d -A config/queues_disk.cfg") - puts "ap4r service has started" - end - - # Stops ap4r service. - def stop_ap4r_service - system("ruby script/mongrel_ap4r stop") - puts "ap4r service has stopped" - end - - # Starts rails service. - # Invokes mongrel_rails, so mongrel_rails should be installed. - def start_rails_service - system("mongrel_rails start -d --environment test") - puts "rails service has started" - end - - # Stops rails service. - def stop_rails_service - system("mongrel_rails stop") - puts "rails service has stopped" - end - # Requests to sync_hello/execute_via_*. # Implemented by using net/http, not by +post+ method of rails integration test. # There's plenty of scope for refinement. From shino at rubyforge.org Tue May 29 01:50:30 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 29 May 2007 01:50:30 -0400 (EDT) Subject: [ap4r-devel] [205] trunk/samples/HelloWorld: add test case: Message-ID: <20070529055030.2AD015240C41@rubyforge.org> Revision: 205 Author: shino Date: 2007-05-29 01:50:29 -0400 (Tue, 29 May 2007) Log Message: ----------- add test case: test an action whick invoke async_to with SAF (execute_with_saf). Now the test result is dependent on fine-tuning of sleep times in both action and test case. Needs powerful control over rails service and ap4r service (particularly ap4r side). Modified Paths: -------------- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb =================================================================== --- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-29 05:00:26 UTC (rev 204) +++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-29 05:50:29 UTC (rev 205) @@ -55,7 +55,7 @@ ap4r.transaction do write('Hello') - req = {:world_id => rand(100), :message => "World"} + req = {:world_id => rand(100), :message => "World", :sleep => params[:sleep]} ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req) Modified: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-29 05:00:26 UTC (rev 204) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-29 05:50:29 UTC (rev 205) @@ -1,7 +1,25 @@ require "#{File.dirname(__FILE__)}/../../test_helper" +require 'reliable-msg' +require 'ap4r' + +class Ap4rTestHelper + + def clear(*queues) + end + +end + +ap4r_test_helper = Ap4rTestHelper.new + class Test::Unit::TestCase + cattr_accessor :ap4r_helper + + def ap4r_helper + @@ap4r_helper + end + # Starts rails service and ap4r service. # After block execution, stops both. def with_services @@ -19,6 +37,13 @@ end end + def wait_for_saf_forward + loop do + count = ::Ap4r::StoredMessage.count(:conditions => {:status => ::Ap4r::StoredMessage::STATUS_STORED}) + break if count == 0 + end + end + # Starts ap4r service. # Uses script at script/mongrel_ap4r. def start_ap4r_service Modified: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-29 05:00:26 UTC (rev 204) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-29 05:50:29 UTC (rev 205) @@ -13,13 +13,23 @@ # class HelloWorldStoriesTest < ActionController::IntegrationTest - def test_start_ap4r_server + def test_http_dispatch with_services do assert_one_line_added do - say_hello(:with => :http) + say_hello(:via => :http) end + assert_one_line_added do + join_async_world + end + end + end + def test_http_dispatch_with_saf + with_services do assert_one_line_added do + say_hello(:with => :saf) + end + assert_one_line_added do join_async_world end end @@ -31,17 +41,21 @@ # Implemented by using net/http, not by +post+ method of rails integration test. # There's plenty of scope for refinement. def say_hello(options) - options[:via] ||= :http + via_option = options[:via] ? "_via_#{options[:via].to_s.downcase}" : "" + with_option = options[:with] ? "_with_#{options[:with].to_s.downcase}" : "" + Net::HTTP.start("localhost", 3000) do |http| - http.request_post("/sync_hello/execute_via_#{options[:via].to_s.downcase}", - "sleep=1") + http.request_post("/sync_hello/execute#{via_option}#{with_option}", + "sleep=0.5") end end # Waits for async logic to finish. # Not what-is-called join, but just sleep. def join_async_world - sleep 2 + sleep 0.5 + wait_for_saf_forward + sleep 0.5 end # returns line count of HelloWorld.txt file From shino at rubyforge.org Tue May 29 02:31:27 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 29 May 2007 02:31:27 -0400 (EDT) Subject: [ap4r-devel] [206] trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r: Refactoring: one step forward to finer control of ap4r Message-ID: <20070529063127.601B55240C41@rubyforge.org> Revision: 206 Author: shino Date: 2007-05-29 02:31:27 -0400 (Tue, 29 May 2007) Log Message: ----------- Refactoring: one step forward to finer control of ap4r Modified Paths: -------------- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb Modified: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-29 05:50:29 UTC (rev 205) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-29 06:31:27 UTC (rev 206) @@ -1,19 +1,81 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + require "#{File.dirname(__FILE__)}/../../test_helper" +require 'erb' +require 'yaml' require 'reliable-msg' require 'ap4r' + + class Ap4rTestHelper - def clear(*queues) + 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 + @qm = nil end -end + # Starts ap4r service. + def start_ap4r_service(wait_until_started = true) -ap4r_test_helper = Ap4rTestHelper.new + 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 -class Test::Unit::TestCase + # TODO: need to wait until ap4r has really started 2007/05/28 by shino + loop do + begin + @qm = DRbObject.new_with_uri("druby://localhost:#{@test_server_config.drb["port"]}") + if @qm.alive? + puts "ap4r service has started" + break + end + rescue => e + sleep 0.5 + end + end + end + # Stops ap4r service. + def stop_ap4r_service + command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " + + "stop -c #{@root_dir}" + print "executing command: #{command} ..." + system(command) + puts + + @qm = nil + puts "ap4r service has stopped" + end + + def clear(*queues) + queues.each do |queue| + q = ReliableMsg::Queue.new(queue) + loop do + break unless q.get + end + end + end + cattr_accessor :ap4r_helper def ap4r_helper @@ -27,7 +89,6 @@ start_rails_service begin start_ap4r_service - sleep 1 # make sure yield ensure stop_ap4r_service @@ -44,19 +105,6 @@ end end - # Starts ap4r service. - # Uses script at script/mongrel_ap4r. - def start_ap4r_service - system("ruby script/mongrel_ap4r start -d -A config/queues_disk.cfg") - puts "ap4r service has started" - end - - # Stops ap4r service. - def stop_ap4r_service - system("ruby script/mongrel_ap4r stop") - puts "ap4r service has stopped" - end - # Starts rails service. # Invokes mongrel_rails, so mongrel_rails should be installed. def start_rails_service @@ -70,5 +118,28 @@ puts "rails service has stopped" end + end +ap4r_test_helper = Ap4rTestHelper.new + +# at_exit { +# ap4r_test_helper.stop_service() +# } + +# ap4r_test_helper.start_service() + +class Test::Unit::TestCase + cattr_accessor :ap4r_helper + + def ap4r_helper + @@ap4r_helper + end + + def with_services(&block) + ap4r_helper.with_services(&block) + end +end + +Test::Unit::TestCase.ap4r_helper = ap4r_test_helper + Modified: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-29 05:50:29 UTC (rev 205) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-29 06:31:27 UTC (rev 206) @@ -11,27 +11,35 @@ # - Workspaces of ap4r and rails should have some conventions for convinience. # - Think about transition to RSpec. # -class HelloWorldStoriesTest < ActionController::IntegrationTest +class HelloWorldStoriesTest < Test::Unit::TestCase def test_http_dispatch with_services do - assert_one_line_added do + assert_lines_added(2) do say_hello(:via => :http) - end - assert_one_line_added do join_async_world end +# assert_one_line_added do +# say_hello(:via => :http) +# end +# assert_one_line_added do +# join_async_world +# end end end def test_http_dispatch_with_saf with_services do - assert_one_line_added do + assert_lines_added(2) do say_hello(:with => :saf) - end - assert_one_line_added do join_async_world end +# assert_one_line_added do +# say_hello(:with => :saf) +# end +# assert_one_line_added do +# join_async_world +# end end end @@ -54,7 +62,7 @@ # Not what-is-called join, but just sleep. def join_async_world sleep 0.5 - wait_for_saf_forward + ap4r_helper.wait_for_saf_forward sleep 0.5 end @@ -63,14 +71,14 @@ `wc -l public/HelloWorld.txt`.to_i end - def assert_lines_added(initial, delta) + def assert_lines_added(delta) + initial = line_count + yield assert_equal (initial + delta), line_count end - def assert_one_line_added - initial = line_count - yield - assert_lines_added(initial, 1) + def assert_one_line_added(&block) + assert_lines_added(1, &block) end end From kato-k at rubyforge.org Tue May 29 02:59:56 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Tue, 29 May 2007 02:59:56 -0400 (EDT) Subject: [ap4r-devel] [207] trunk/samples/HelloWorld/app/controllers/saf_controller.rb: Renamed method for asyncronous call and added comment. Message-ID: <20070529065956.C5BCAA97000B@rubyforge.org> Revision: 207 Author: kato-k Date: 2007-05-29 02:59:56 -0400 (Tue, 29 May 2007) Log Message: ----------- Renamed method for asyncronous call and added comment. Modified Paths: -------------- trunk/samples/HelloWorld/app/controllers/saf_controller.rb Modified: trunk/samples/HelloWorld/app/controllers/saf_controller.rb =================================================================== --- trunk/samples/HelloWorld/app/controllers/saf_controller.rb 2007-05-29 06:31:27 UTC (rev 206) +++ trunk/samples/HelloWorld/app/controllers/saf_controller.rb 2007-05-29 06:59:56 UTC (rev 207) @@ -53,11 +53,11 @@ def recovery @stored_message = ::Ap4r::StoredMessage.find(params[:id]) - async_dispatch(Marshal::load(@stored_message.object), + ap4r.async_to(Marshal::load(@stored_message.object), {}, Marshal::load(@stored_message.headers).merge({ :queue => @stored_message.queue})) - @stored_message.status = 2 + @stored_message.status = 2 # change status value for now, let's destroy if it's unnecessary. @stored_message.save redirect_to :action => 'list' From kato-k at rubyforge.org Tue May 29 06:44:41 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Tue, 29 May 2007 06:44:41 -0400 (EDT) Subject: [ap4r-devel] [208] trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb: Modified reference to controller object. Message-ID: <20070529104441.AD7395240B50@rubyforge.org> Revision: 208 Author: kato-k Date: 2007-05-29 06:44:41 -0400 (Tue, 29 May 2007) Log Message: ----------- Modified reference to controller object. Modified Paths: -------------- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-29 06:59:56 UTC (rev 207) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-29 10:44:41 UTC (rev 208) @@ -191,7 +191,7 @@ # TODO: clone it, 2006/10/16 shino url_options ||= {} - url_options[:controller] ||= self.controller_path.gsub("/", ".") + url_options[:controller] ||= @controller.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. From kato-k at rubyforge.org Tue May 29 06:45:52 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Tue, 29 May 2007 06:45:52 -0400 (EDT) Subject: [ap4r-devel] [209] trunk/samples/HelloWorld/app/controllers/saf_controller.rb: Changed arguments order for async_to method. Message-ID: <20070529104552.CBF575240B50@rubyforge.org> Revision: 209 Author: kato-k Date: 2007-05-29 06:45:52 -0400 (Tue, 29 May 2007) Log Message: ----------- Changed arguments order for async_to method. Modified Paths: -------------- trunk/samples/HelloWorld/app/controllers/saf_controller.rb Modified: trunk/samples/HelloWorld/app/controllers/saf_controller.rb =================================================================== --- trunk/samples/HelloWorld/app/controllers/saf_controller.rb 2007-05-29 10:44:41 UTC (rev 208) +++ trunk/samples/HelloWorld/app/controllers/saf_controller.rb 2007-05-29 10:45:52 UTC (rev 209) @@ -53,10 +53,15 @@ def recovery @stored_message = ::Ap4r::StoredMessage.find(params[:id]) - ap4r.async_to(Marshal::load(@stored_message.object), - {}, - Marshal::load(@stored_message.headers).merge({ :queue => @stored_message.queue})) + headers = Marshal::load(@stored_message.headers) + body = Marshal::load(@stored_message.object) + url_options = {:controller => 'dummy'} # url is overwritten by :target_url in rm_options + async_params = body + rm_options = headers.merge({ :queue => @stored_message.queue}) + + ap4r.async_to(url_options, async_params, rm_options) + @stored_message.status = 2 # change status value for now, let's destroy if it's unnecessary. @stored_message.save From kato-k at rubyforge.org Wed May 30 04:16:29 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Wed, 30 May 2007 04:16:29 -0400 (EDT) Subject: [ap4r-devel] [210] trunk/samples/HelloWorld: Experimental implementation: Changed the structure of url_options argument for async_to method. Message-ID: <20070530081629.D8DDA5240ADC@rubyforge.org> Revision: 210 Author: kato-k Date: 2007-05-30 04:16:23 -0400 (Wed, 30 May 2007) Log Message: ----------- Experimental implementation: Changed the structure of url_options argument for async_to method. Is it redundant api? Modified Paths: -------------- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb =================================================================== --- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-29 10:45:52 UTC (rev 209) +++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-30 08:16:23 UTC (rev 210) @@ -11,15 +11,18 @@ write('Hello') req = {:world_id => rand(100), :message => "World", :sleep => params[:sleep]} - ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, req) + ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_http'}}, req ) + # It's possible to directly pass url as an argument. + #ap4r.async_to({:url => 'http://localhost:3000/async_world/execute_via_http/'}, req) + render :nothing => true end def execute_with_block write('Hello') - ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}) do + ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_http'}} ) do # basic #body :hoge, "hoge" @@ -56,7 +59,7 @@ write('Hello') req = {:world_id => rand(100), :message => "World", :sleep => params[:sleep]} - ap4r.async_to({:controller => 'async_world', :action => 'execute_via_http'}, + ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_http'}}, req) render :nothing => true @@ -67,7 +70,7 @@ write('Hello') req = WorldRequest.new(:world_id => rand(100), :message => "World") - ap4r.async_to({:controller => 'async_world', :action => 'execute_via_ws'}, + ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_ws'}}, req, {:dispatch_mode => :XMLRPC} ) @@ -78,7 +81,7 @@ write('Hello') req = WorldRequest.new(:world_id => rand(100), :message => "World") - ap4r.async_to({:controller => 'async_world', :action => 'execute_via_ws'}, + ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_ws'}}, req, {:dispatch_mode => :SOAP} ) Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-29 10:45:52 UTC (rev 209) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-30 08:16:23 UTC (rev 210) @@ -191,7 +191,7 @@ # TODO: clone it, 2006/10/16 shino url_options ||= {} - url_options[:controller] ||= @controller.controller_path.gsub("/", ".") + url_options[:url][:controller] ||= @controller.controller_path.gsub("/", ".") if url_options[:url].kind_of?(Hash) rm_options = @@default_rm_options.merge(rm_options || {}) # Only async_params is not cloned. options and rm_options are cloned before now. @@ -235,8 +235,13 @@ 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) + if options[:url].kind_of?(Hash) + rm_options[:queue_name] ||= + @@default_queue_prefix.clone.concat(options[:url][:controller].to_s).concat('.').concat(options[:url][:action].to_s) + else + rm_options[:queue_name] ||= + @@default_queue_prefix.clone.chomp(".").concat(URI::parse(options[:url]).path.gsub("/", ".")) + end rm_options[:queue_name] end @@ -281,6 +286,7 @@ private # helper method for ActionController#url_for def url_for(url_for_options, *parameter_for_method_reference) + return url_for_options if url_for_options.kind_of?(String) @url_for_handler.url_for(url_for_options, *parameter_for_method_reference) end @@ -294,7 +300,7 @@ end def make_rm_options - @rm_options[:target_url] ||= url_for(@url_options) + @rm_options[:target_url] ||= url_for(@url_options[:url]) @rm_options[:target_method] ||= 'POST' #TODO: make option key to specify HTTP headers, 2006/10/16 shino @rm_options @@ -315,14 +321,12 @@ end def action_api_name - action_method_name = @url_options[:action] + action_method_name = @url_options[:url][:action] action_method_name.camelcase end def options_without_action - new_opts = @url_options.dup - new_opts[:action] = nil - new_opts + @url_options[:url].reject{ |k,v| k == :action } end end From shino at rubyforge.org Wed May 30 04:20:30 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Wed, 30 May 2007 04:20:30 -0400 (EDT) Subject: [ap4r-devel] [211] trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r: test case refinement with rails and ap4r Message-ID: <20070530082030.B74F45240ADC@rubyforge.org> Revision: 211 Author: shino Date: 2007-05-30 04:20:27 -0400 (Wed, 30 May 2007) Log Message: ----------- test case refinement with rails and ap4r Modified Paths: -------------- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb Modified: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-30 08:16:23 UTC (rev 210) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-30 08:20:27 UTC (rev 211) @@ -2,15 +2,14 @@ # Copyright:: Copyright (c) 2007 Future Architect Inc. # Licence:: MIT Licence -require "#{File.dirname(__FILE__)}/../../test_helper" +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../../../config/environment") require 'erb' require 'yaml' require 'reliable-msg' require 'ap4r' - - class Ap4rTestHelper def initialize(config_file = RAILS_ROOT + "/config/ap4r.yml") @@ -32,6 +31,10 @@ @qm = nil end + def qm + @qm ||= DRbObject.new_with_uri("druby://localhost:#{@test_server_config.drb["port"]}") + end + # Starts ap4r service. def start_ap4r_service(wait_until_started = true) @@ -39,18 +42,18 @@ "start -d -c #{@root_dir} -A #{@config_file}" print "executing command: #{command} ..." system(command) - puts - # TODO: need to wait until ap4r has really started 2007/05/28 by shino - loop do + return unless wait_until_started + 50.times do + print "." begin - @qm = DRbObject.new_with_uri("druby://localhost:#{@test_server_config.drb["port"]}") - if @qm.alive? + if qm.alive? + puts puts "ap4r service has started" - break + return end rescue => e - sleep 0.5 + sleep 0.2 end end end @@ -68,6 +71,7 @@ end def clear(*queues) + raise "not yet implemented" queues.each do |queue| q = ReliableMsg::Queue.new(queue) loop do @@ -76,32 +80,27 @@ end end - cattr_accessor :ap4r_helper - - def ap4r_helper - @@ap4r_helper - end - # Starts rails service and ap4r service. # After block execution, stops both. - def with_services - begin - start_rails_service - begin - start_ap4r_service - yield - ensure - stop_ap4r_service - end - ensure - stop_rails_service - end - end +# def with_services +# begin +# start_rails_service +# begin +# start_ap4r_service +# yield +# ensure +# stop_ap4r_service +# end +# ensure +# stop_rails_service +# end +# end def wait_for_saf_forward - loop do + 50.times do count = ::Ap4r::StoredMessage.count(:conditions => {:status => ::Ap4r::StoredMessage::STATUS_STORED}) break if count == 0 + sleep 0.2 end end @@ -118,16 +117,37 @@ puts "rails service has stopped" end + def start_dispatchers + qm.dispatchers.start + end + def stop_dispatchers + qm.dispatchers.stop + end + + def wait_all_done + 50.times do + break if flag = qm.no_active_message? + sleep 0.2 + end + end + + def dlq + qm.list :queue => "$dlq" + end + end + ap4r_test_helper = Ap4rTestHelper.new +ap4r_test_helper.start_rails_service +at_exit { ap4r_test_helper.stop_rails_service } -# at_exit { -# ap4r_test_helper.stop_service() -# } +ap4r_test_helper.start_ap4r_service +at_exit { ap4r_test_helper.stop_ap4r_service } -# ap4r_test_helper.start_service() +# Test::Unit also use at_exit hook, so load at the end +require "#{File.dirname(__FILE__)}/../../test_helper" class Test::Unit::TestCase cattr_accessor :ap4r_helper @@ -136,10 +156,9 @@ @@ap4r_helper end - def with_services(&block) - ap4r_helper.with_services(&block) - end +# def with_services(&block) +# ap4r_helper.with_services(&block) +# end end Test::Unit::TestCase.ap4r_helper = ap4r_test_helper - Modified: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-30 08:16:23 UTC (rev 210) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-30 08:20:27 UTC (rev 211) @@ -14,33 +14,30 @@ class HelloWorldStoriesTest < Test::Unit::TestCase def test_http_dispatch - with_services do - assert_lines_added(2) do + puts "test case invoked" +# with_services do + ap4r_helper.stop_dispatchers + assert_one_line_added do say_hello(:via => :http) + end + ap4r_helper.start_dispatchers + assert_one_line_added do join_async_world end -# assert_one_line_added do -# say_hello(:via => :http) -# end -# assert_one_line_added do -# join_async_world -# end - end +# end end def test_http_dispatch_with_saf - with_services do - assert_lines_added(2) do +# with_services do + ap4r_helper.stop_dispatchers + assert_one_line_added do say_hello(:with => :saf) + end + ap4r_helper.start_dispatchers + assert_one_line_added do join_async_world end -# assert_one_line_added do -# say_hello(:with => :saf) -# end -# assert_one_line_added do -# join_async_world -# end - end +# end end private @@ -59,11 +56,8 @@ end # Waits for async logic to finish. - # Not what-is-called join, but just sleep. def join_async_world - sleep 0.5 - ap4r_helper.wait_for_saf_forward - sleep 0.5 + ap4r_helper.wait_all_done end # returns line count of HelloWorld.txt file From shino at rubyforge.org Wed May 30 04:21:11 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Wed, 30 May 2007 04:21:11 -0400 (EDT) Subject: [ap4r-devel] [212] trunk/ap4r/lib/ap4r: add utility/accessor methods for testing Message-ID: <20070530082111.6222C5240ADC@rubyforge.org> Revision: 212 Author: shino Date: 2007-05-30 04:21:10 -0400 (Wed, 30 May 2007) Log Message: ----------- add utility/accessor methods for testing Modified Paths: -------------- trunk/ap4r/lib/ap4r/dispatcher.rb trunk/ap4r/lib/ap4r/queue_manager_ext_debug.rb Modified: trunk/ap4r/lib/ap4r/dispatcher.rb =================================================================== --- trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-30 08:20:27 UTC (rev 211) +++ trunk/ap4r/lib/ap4r/dispatcher.rb 2007-05-30 08:21:10 UTC (rev 212) @@ -48,6 +48,7 @@ @@logger ||= logger_obj raise "no configuration specified" unless @config @group = ThreadGroup.new + # TODO: needs refinement 2007/05/30 by shino @dispatch_targets = "" end @@ -84,6 +85,7 @@ return unless @group @group.list.each {|d| d[:dying] = true} @group.list.each {|d| d.join } + @dispatch_targets = "" end private Modified: trunk/ap4r/lib/ap4r/queue_manager_ext_debug.rb =================================================================== --- trunk/ap4r/lib/ap4r/queue_manager_ext_debug.rb 2007-05-30 08:20:27 UTC (rev 211) +++ trunk/ap4r/lib/ap4r/queue_manager_ext_debug.rb 2007-05-30 08:21:10 UTC (rev 212) @@ -6,7 +6,7 @@ module ReliableMsg class QueueManager - attr_reader :store, :transactions, :mutex, :config + attr_reader :store, :transactions, :mutex, :config, :dispatchers, :carriers # Accepts ruby code as a string, evaluates it on +self+, # and returns the result as a formatted string. @@ -38,6 +38,9 @@ end alias e2i eval_to_inspect + def no_active_message? + @transactions.size.zero? && @store.queues.all?{|(q, ms)| q == "$dlq" || ms.size.zero? } + end end module MessageStore From shino at rubyforge.org Wed May 30 04:24:52 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Wed, 30 May 2007 04:24:52 -0400 (EDT) Subject: [ap4r-devel] [213] trunk/ap4r/script/mongrel_ap4r.rb: typo fix Message-ID: <20070530082452.BC28E5240C65@rubyforge.org> Revision: 213 Author: shino Date: 2007-05-30 04:24:52 -0400 (Wed, 30 May 2007) Log Message: ----------- typo fix add check docroot Modified Paths: -------------- trunk/ap4r/script/mongrel_ap4r.rb Modified: trunk/ap4r/script/mongrel_ap4r.rb =================================================================== --- trunk/ap4r/script/mongrel_ap4r.rb 2007-05-30 08:21:10 UTC (rev 212) +++ trunk/ap4r/script/mongrel_ap4r.rb 2007-05-30 08:24:52 UTC (rev 213) @@ -1,5 +1,5 @@ # Author:: Shunichi Shinohara -# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Copyright:: Copyright (c) 2007 Future Architect Corp. # Licence:: MIT Licence require 'rubygems' @@ -86,8 +86,7 @@ valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file" valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file" - # TODO: now not utilized, skip checking 2007/04/23 by shino - #valid_dir? @docroot, "Path to docroot not valid: #@docroot" + valid_dir? @docroot, "Path to docroot not valid: #@docroot" return @valid end From shino at rubyforge.org Wed May 30 04:28:46 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Wed, 30 May 2007 04:28:46 -0400 (EDT) Subject: [ap4r-devel] [214] trunk/samples/HelloWorld/script/mongrel_ap4r.sample: remove test script disused Message-ID: <20070530082847.0CDFE5240C86@rubyforge.org> Revision: 214 Author: shino Date: 2007-05-30 04:28:46 -0400 (Wed, 30 May 2007) Log Message: ----------- remove test script disused Removed Paths: ------------- trunk/samples/HelloWorld/script/mongrel_ap4r.sample Deleted: trunk/samples/HelloWorld/script/mongrel_ap4r.sample =================================================================== --- trunk/samples/HelloWorld/script/mongrel_ap4r.sample 2007-05-30 08:24:52 UTC (rev 213) +++ trunk/samples/HelloWorld/script/mongrel_ap4r.sample 2007-05-30 08:28:46 UTC (rev 214) @@ -1,3 +0,0 @@ -#!/bin/sh -cd ~/work/ap4r_projects/trunk_test -ruby -I ~/d/ap4r-core-trunk/lib script/mongrel_ap4r.rb $* From shino at rubyforge.org Thu May 31 01:30:44 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 31 May 2007 01:30:44 -0400 (EDT) Subject: [ap4r-devel] [215] trunk/samples/HelloWorld/test: Log message arrangement in testing. Message-ID: <20070531053044.C602F5240C03@rubyforge.org> Revision: 215 Author: shino Date: 2007-05-31 01:30:42 -0400 (Thu, 31 May 2007) Log Message: ----------- Log message arrangement in testing. Adding a directory for integration test with rails and AP4R servers. Modified Paths: -------------- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb Added Paths: ----------- trunk/samples/HelloWorld/test/async/ Modified: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-30 08:28:46 UTC (rev 214) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-31 05:30:42 UTC (rev 215) @@ -40,16 +40,15 @@ 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} ..." + print "Starting AP4R with command: #{command} ..." system(command) - + print "and waiting..." return unless wait_until_started 50.times do print "." begin if qm.alive? - puts - puts "ap4r service has started" + puts "Done." return end rescue => e @@ -62,12 +61,9 @@ def stop_ap4r_service command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " + "stop -c #{@root_dir}" - print "executing command: #{command} ..." + puts "Terminating AP4R with command: #{command}." system(command) - puts - @qm = nil - puts "ap4r service has stopped" end def clear(*queues) @@ -107,14 +103,14 @@ # Starts rails service. # Invokes mongrel_rails, so mongrel_rails should be installed. def start_rails_service + print "Starting Mongrel(Rails)..." system("mongrel_rails start -d --environment test") - puts "rails service has started" + puts "Done." end # Stops rails service. def stop_rails_service system("mongrel_rails stop") - puts "rails service has stopped" end def start_dispatchers Modified: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-30 08:28:46 UTC (rev 214) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-31 05:30:42 UTC (rev 215) @@ -14,7 +14,6 @@ class HelloWorldStoriesTest < Test::Unit::TestCase def test_http_dispatch - puts "test case invoked" # with_services do ap4r_helper.stop_dispatchers assert_one_line_added do From shino at rubyforge.org Thu May 31 01:31:58 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 31 May 2007 01:31:58 -0400 (EDT) Subject: [ap4r-devel] [216] trunk/samples/HelloWorld/test: move files from temporary directory Message-ID: <20070531053158.C94745240AEC@rubyforge.org> Revision: 216 Author: shino Date: 2007-05-31 01:31:58 -0400 (Thu, 31 May 2007) Log Message: ----------- move files from temporary directory Added Paths: ----------- trunk/samples/HelloWorld/test/async/ap4r_test_helper.rb trunk/samples/HelloWorld/test/async/hello_world_stories_test.rb Removed Paths: ------------- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb Copied: trunk/samples/HelloWorld/test/async/ap4r_test_helper.rb (from rev 215, trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb) =================================================================== --- trunk/samples/HelloWorld/test/async/ap4r_test_helper.rb (rev 0) +++ trunk/samples/HelloWorld/test/async/ap4r_test_helper.rb 2007-05-31 05:31:58 UTC (rev 216) @@ -0,0 +1,160 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +ENV["RAILS_ENV"] = "test" +require File.expand_path(File.dirname(__FILE__) + "/../../../config/environment") + +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 + @qm = nil + end + + def qm + @qm ||= DRbObject.new_with_uri("druby://localhost:#{@test_server_config.drb["port"]}") + end + + # Starts ap4r service. + def start_ap4r_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 "Starting AP4R with command: #{command} ..." + system(command) + print "and waiting..." + return unless wait_until_started + 50.times do + print "." + begin + if qm.alive? + puts "Done." + return + end + rescue => e + sleep 0.2 + end + end + end + + # Stops ap4r service. + def stop_ap4r_service + command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " + + "stop -c #{@root_dir}" + puts "Terminating AP4R with command: #{command}." + system(command) + @qm = nil + end + + def clear(*queues) + raise "not yet implemented" + queues.each do |queue| + q = ReliableMsg::Queue.new(queue) + loop do + break unless q.get + end + end + end + + # Starts rails service and ap4r service. + # After block execution, stops both. +# def with_services +# begin +# start_rails_service +# begin +# start_ap4r_service +# yield +# ensure +# stop_ap4r_service +# end +# ensure +# stop_rails_service +# end +# end + + def wait_for_saf_forward + 50.times do + count = ::Ap4r::StoredMessage.count(:conditions => {:status => ::Ap4r::StoredMessage::STATUS_STORED}) + break if count == 0 + sleep 0.2 + end + end + + # Starts rails service. + # Invokes mongrel_rails, so mongrel_rails should be installed. + def start_rails_service + print "Starting Mongrel(Rails)..." + system("mongrel_rails start -d --environment test") + puts "Done." + end + + # Stops rails service. + def stop_rails_service + system("mongrel_rails stop") + end + + def start_dispatchers + qm.dispatchers.start + end + + def stop_dispatchers + qm.dispatchers.stop + end + + def wait_all_done + 50.times do + break if flag = qm.no_active_message? + sleep 0.2 + end + end + + def dlq + qm.list :queue => "$dlq" + end + +end + + +ap4r_test_helper = Ap4rTestHelper.new +ap4r_test_helper.start_rails_service +at_exit { ap4r_test_helper.stop_rails_service } + +ap4r_test_helper.start_ap4r_service +at_exit { ap4r_test_helper.stop_ap4r_service } + +# Test::Unit also use at_exit hook, so load at the end +require "#{File.dirname(__FILE__)}/../../test_helper" + +class Test::Unit::TestCase + cattr_accessor :ap4r_helper + + def ap4r_helper + @@ap4r_helper + end + +# def with_services(&block) +# ap4r_helper.with_services(&block) +# end +end + +Test::Unit::TestCase.ap4r_helper = ap4r_test_helper Copied: trunk/samples/HelloWorld/test/async/hello_world_stories_test.rb (from rev 215, trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb) =================================================================== --- trunk/samples/HelloWorld/test/async/hello_world_stories_test.rb (rev 0) +++ trunk/samples/HelloWorld/test/async/hello_world_stories_test.rb 2007-05-31 05:31:58 UTC (rev 216) @@ -0,0 +1,77 @@ +require "#{File.dirname(__FILE__)}/ap4r_test_helper" + +require 'net/http' + +# Trial implementation of test cases with ap4r integration. +# some comments: +# - Subclassing IntegrationTest is adequate? +# - Clearance of data in a database and queues should be included. +# - AP4R server can be running in process? +# - dispatcher control is needed for split assertions between (a)sync logics. +# - Workspaces of ap4r and rails should have some conventions for convinience. +# - Think about transition to RSpec. +# +class HelloWorldStoriesTest < Test::Unit::TestCase + + def test_http_dispatch +# with_services do + ap4r_helper.stop_dispatchers + assert_one_line_added do + say_hello(:via => :http) + end + ap4r_helper.start_dispatchers + assert_one_line_added do + join_async_world + end +# end + end + + def test_http_dispatch_with_saf +# with_services do + ap4r_helper.stop_dispatchers + assert_one_line_added do + say_hello(:with => :saf) + end + ap4r_helper.start_dispatchers + assert_one_line_added do + join_async_world + end +# end + end + + private + + # Requests to sync_hello/execute_via_*. + # Implemented by using net/http, not by +post+ method of rails integration test. + # There's plenty of scope for refinement. + def say_hello(options) + via_option = options[:via] ? "_via_#{options[:via].to_s.downcase}" : "" + with_option = options[:with] ? "_with_#{options[:with].to_s.downcase}" : "" + + Net::HTTP.start("localhost", 3000) do |http| + http.request_post("/sync_hello/execute#{via_option}#{with_option}", + "sleep=0.5") + end + end + + # Waits for async logic to finish. + def join_async_world + ap4r_helper.wait_all_done + end + + # returns line count of HelloWorld.txt file + def line_count + `wc -l public/HelloWorld.txt`.to_i + end + + def assert_lines_added(delta) + initial = line_count + yield + assert_equal (initial + delta), line_count + end + + def assert_one_line_added(&block) + assert_lines_added(1, &block) + end + +end Deleted: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-31 05:30:42 UTC (rev 215) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ap4r_test_helper.rb 2007-05-31 05:31:58 UTC (rev 216) @@ -1,160 +0,0 @@ -# Author:: Shunichi Shinohara -# Copyright:: Copyright (c) 2007 Future Architect Inc. -# Licence:: MIT Licence - -ENV["RAILS_ENV"] = "test" -require File.expand_path(File.dirname(__FILE__) + "/../../../config/environment") - -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 - @qm = nil - end - - def qm - @qm ||= DRbObject.new_with_uri("druby://localhost:#{@test_server_config.drb["port"]}") - end - - # Starts ap4r service. - def start_ap4r_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 "Starting AP4R with command: #{command} ..." - system(command) - print "and waiting..." - return unless wait_until_started - 50.times do - print "." - begin - if qm.alive? - puts "Done." - return - end - rescue => e - sleep 0.2 - end - end - end - - # Stops ap4r service. - def stop_ap4r_service - command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " + - "stop -c #{@root_dir}" - puts "Terminating AP4R with command: #{command}." - system(command) - @qm = nil - end - - def clear(*queues) - raise "not yet implemented" - queues.each do |queue| - q = ReliableMsg::Queue.new(queue) - loop do - break unless q.get - end - end - end - - # Starts rails service and ap4r service. - # After block execution, stops both. -# def with_services -# begin -# start_rails_service -# begin -# start_ap4r_service -# yield -# ensure -# stop_ap4r_service -# end -# ensure -# stop_rails_service -# end -# end - - def wait_for_saf_forward - 50.times do - count = ::Ap4r::StoredMessage.count(:conditions => {:status => ::Ap4r::StoredMessage::STATUS_STORED}) - break if count == 0 - sleep 0.2 - end - end - - # Starts rails service. - # Invokes mongrel_rails, so mongrel_rails should be installed. - def start_rails_service - print "Starting Mongrel(Rails)..." - system("mongrel_rails start -d --environment test") - puts "Done." - end - - # Stops rails service. - def stop_rails_service - system("mongrel_rails stop") - end - - def start_dispatchers - qm.dispatchers.start - end - - def stop_dispatchers - qm.dispatchers.stop - end - - def wait_all_done - 50.times do - break if flag = qm.no_active_message? - sleep 0.2 - end - end - - def dlq - qm.list :queue => "$dlq" - end - -end - - -ap4r_test_helper = Ap4rTestHelper.new -ap4r_test_helper.start_rails_service -at_exit { ap4r_test_helper.stop_rails_service } - -ap4r_test_helper.start_ap4r_service -at_exit { ap4r_test_helper.stop_ap4r_service } - -# Test::Unit also use at_exit hook, so load at the end -require "#{File.dirname(__FILE__)}/../../test_helper" - -class Test::Unit::TestCase - cattr_accessor :ap4r_helper - - def ap4r_helper - @@ap4r_helper - end - -# def with_services(&block) -# ap4r_helper.with_services(&block) -# end -end - -Test::Unit::TestCase.ap4r_helper = ap4r_test_helper Deleted: trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-31 05:30:42 UTC (rev 215) +++ trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/hello_world_stories_test.rb 2007-05-31 05:31:58 UTC (rev 216) @@ -1,77 +0,0 @@ -require "#{File.dirname(__FILE__)}/ap4r_test_helper" - -require 'net/http' - -# Trial implementation of test cases with ap4r integration. -# some comments: -# - Subclassing IntegrationTest is adequate? -# - Clearance of data in a database and queues should be included. -# - AP4R server can be running in process? -# - dispatcher control is needed for split assertions between (a)sync logics. -# - Workspaces of ap4r and rails should have some conventions for convinience. -# - Think about transition to RSpec. -# -class HelloWorldStoriesTest < Test::Unit::TestCase - - def test_http_dispatch -# with_services do - ap4r_helper.stop_dispatchers - assert_one_line_added do - say_hello(:via => :http) - end - ap4r_helper.start_dispatchers - assert_one_line_added do - join_async_world - end -# end - end - - def test_http_dispatch_with_saf -# with_services do - ap4r_helper.stop_dispatchers - assert_one_line_added do - say_hello(:with => :saf) - end - ap4r_helper.start_dispatchers - assert_one_line_added do - join_async_world - end -# end - end - - private - - # Requests to sync_hello/execute_via_*. - # Implemented by using net/http, not by +post+ method of rails integration test. - # There's plenty of scope for refinement. - def say_hello(options) - via_option = options[:via] ? "_via_#{options[:via].to_s.downcase}" : "" - with_option = options[:with] ? "_with_#{options[:with].to_s.downcase}" : "" - - Net::HTTP.start("localhost", 3000) do |http| - http.request_post("/sync_hello/execute#{via_option}#{with_option}", - "sleep=0.5") - end - end - - # Waits for async logic to finish. - def join_async_world - ap4r_helper.wait_all_done - end - - # returns line count of HelloWorld.txt file - def line_count - `wc -l public/HelloWorld.txt`.to_i - end - - def assert_lines_added(delta) - initial = line_count - yield - assert_equal (initial + delta), line_count - end - - def assert_one_line_added(&block) - assert_lines_added(1, &block) - end - -end From kato-k at rubyforge.org Thu May 31 02:04:28 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Thu, 31 May 2007 02:04:28 -0400 (EDT) Subject: [ap4r-devel] [217] trunk/samples/HelloWorld: Modified url_options expression for async_to method, now it's possible to allow old api. Message-ID: <20070531060428.158F55240BFA@rubyforge.org> Revision: 217 Author: kato-k Date: 2007-05-31 02:04:27 -0400 (Thu, 31 May 2007) Log Message: ----------- Modified url_options expression for async_to method, now it's possible to allow old api. Modified Paths: -------------- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb Modified: trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb =================================================================== --- trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-31 05:31:58 UTC (rev 216) +++ trunk/samples/HelloWorld/app/controllers/sync_hello_controller.rb 2007-05-31 06:04:27 UTC (rev 217) @@ -11,18 +11,21 @@ write('Hello') req = {:world_id => rand(100), :message => "World", :sleep => params[:sleep]} - ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_http'}}, req ) + ap4r.async_to( {:controller => 'async_world', :action => 'execute_via_http'}, req ) - # It's possible to directly pass url as an argument. - #ap4r.async_to({:url => 'http://localhost:3000/async_world/execute_via_http/'}, req) + # The following expression is equivalent, + #ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_http'}}, req ) + # and it's possible to directly pass url as an argument. + #ap4r.async_to( {:url => 'http://localhost:3000/async_world/execute_via_http/'}, req ) + render :nothing => true end def execute_with_block write('Hello') - ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_http'}} ) do + ap4r.async_to( {:controller => 'async_world', :action => 'execute_via_http'} ) do # basic #body :hoge, "hoge" @@ -59,7 +62,7 @@ write('Hello') req = {:world_id => rand(100), :message => "World", :sleep => params[:sleep]} - ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_http'}}, + ap4r.async_to( {:controller => 'async_world', :action => 'execute_via_http'}, req) render :nothing => true @@ -70,7 +73,7 @@ write('Hello') req = WorldRequest.new(:world_id => rand(100), :message => "World") - ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_ws'}}, + ap4r.async_to( {:controller => 'async_world', :action => 'execute_via_ws'}, req, {:dispatch_mode => :XMLRPC} ) @@ -81,7 +84,7 @@ write('Hello') req = WorldRequest.new(:world_id => rand(100), :message => "World") - ap4r.async_to( {:url => {:controller => 'async_world', :action => 'execute_via_ws'}}, + ap4r.async_to( {:controller => 'async_world', :action => 'execute_via_ws'}, req, {:dispatch_mode => :SOAP} ) Modified: trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-31 05:31:58 UTC (rev 216) +++ trunk/samples/HelloWorld/vendor/plugins/ap4r/lib/async_helper.rb 2007-05-31 06:04:27 UTC (rev 217) @@ -179,7 +179,6 @@ # 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? logger.debug("url_options: ") logger.debug(url_options.inspect) @@ -191,7 +190,10 @@ # TODO: clone it, 2006/10/16 shino url_options ||= {} - url_options[:url][:controller] ||= @controller.controller_path.gsub("/", ".") if url_options[:url].kind_of?(Hash) + url_options[:controller] ||= @controller.controller_path.gsub("/", ".") + url_options[:url] ||= {:controller => url_options[:controller], :action => url_options[:action]} + url_options[:url][:controller] ||= url_options[:controller] if url_options[:url].kind_of?(Hash) + rm_options = @@default_rm_options.merge(rm_options || {}) # Only async_params is not cloned. options and rm_options are cloned before now. From shino at rubyforge.org Thu May 31 02:27:17 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 31 May 2007 02:27:17 -0400 (EDT) Subject: [ap4r-devel] [218] trunk/ap4r: move mongrel_ap4r script to under lib/. Message-ID: <20070531062717.C73425240C00@rubyforge.org> Revision: 218 Author: shino Date: 2007-05-31 02:27:17 -0400 (Thu, 31 May 2007) Log Message: ----------- move mongrel_ap4r script to under lib/. intend that files under script/ are just load lib/something.(see next checkin)" Added Paths: ----------- trunk/ap4r/lib/ap4r/mongrel_ap4r.rb Removed Paths: ------------- trunk/ap4r/script/mongrel_ap4r.rb Copied: trunk/ap4r/lib/ap4r/mongrel_ap4r.rb (from rev 214, trunk/ap4r/script/mongrel_ap4r.rb) =================================================================== --- trunk/ap4r/lib/ap4r/mongrel_ap4r.rb (rev 0) +++ trunk/ap4r/lib/ap4r/mongrel_ap4r.rb 2007-05-31 06:27:17 UTC (rev 218) @@ -0,0 +1,254 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Corp. +# Licence:: MIT Licence + +require 'rubygems' +require 'mongrel' +require 'ap4r/mongrel' + +module Ap4r::Mongrel + + module Command + PREFIX = "ap4r::mongrel::" + + module Base + def self.included(klass) + return unless klass.kind_of?(Class) + klass.class_eval do |k| + include(::Mongrel::Command::Base) + end + # TODO: Can subclass the return of RubyGems::GemPlugin ? 2007/04/16 by shino + end + + # send a signal to the process specified by pid_file. + def send_signal(signal, pid_file) + pid = open(pid_file).read.to_i + print "Send signal #{signal} to AP4R at PID #{pid} ..." + begin + Process.kill(signal, pid) + rescue Errno::ESRCH + puts "Process not found." + end + puts "Done." + end + end + + end + + class Help < GemPlugin::Plugin "/commands" + include ::Ap4r::Mongrel::Command::Base + + def run + puts "Available AP4R commands are:\n\n" + Mongrel::Command::Registry.instance.commands.each do |name| + if name =~ /#{Command::PREFIX}/ + name = name[Command::PREFIX.length .. -1] + end + puts " - #{name[1 .. -1]}\n" + end + puts "\nfor further help, run each command with -h option to get help." + end + + end + + class Version < GemPlugin::Plugin "/commands" + include ::Ap4r::Mongrel::Command::Base + + def run + puts "AP4R Version is:" + puts + puts " - AP4R #{::Ap4r::VERSION::STRING}" + puts + end + + end + + class Start < GemPlugin::Plugin "/commands" + include ::Ap4r::Mongrel::Command::Base + + def configure + options [ + ["-d", "--daemonize", "Run in daemon mode", :@daemon, false], + ['-p', '--port PORT', "Port number used by mongrel", :@port, 7438], + ['-a', '--address HOST', "IP address used by mongrel", :@host, "0.0.0.0"], + ['-A', '--ap4r-config FILE', "Config file for reliable-msg/AP4R", :@ap4r_config_file, "config/queues.cfg"], + ['-l', '--log FILE', "Log file", :@log_file, "log/mongrel_ap4r.log"], + ['-P', '--pid FILE', "PID file", :@pid_file, "log/mongrel_ap4r.pid"], + ['-r', '--root PATH', "Document root (no meanings yet.)", :@docroot, "public"], + ['-c', '--chdir PATH', "Change to dir", :@cwd, Dir.pwd], + ] + end + + def validate + @cwd = File.expand_path(@cwd) + valid_dir? @cwd, "Path of chdir not valid: #@cwd " + Dir.chdir(@cwd) + + valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file" + valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file" + valid_dir? @docroot, "Path to docroot not valid: #@docroot" + + return @valid + end + + def run + settings = { + :host => @host, :port => @port, + :log_file => @log_file, :pid_file => @pid_file, + :docroot => @docroot, + :daemon => @daemon, + :ap4r_config_file => @ap4r_config_file, + } + + config = ::Ap4r::Mongrel::Ap4rConfigurator.new(settings) do + if defaults[:daemon] + if File.exist? defaults[:pid_file] + log "PID file #{defaults[:pid_file]} exists!!! Exiting with error." + exit 1 + end + daemonize({:log_file => @log_file, :cwd => File.expand_path(".") }) + end + + listener do + log "Starting AP4R Handler with #{defaults[:ap4r_config_file]}" + uri "/", :handler => ::Ap4r::Mongrel::Ap4rHandler.new(defaults) + end + setup_signals(settings) + end + + config.run + config.log "Mongrel available at #{settings[:host]}:#{settings[:port]}" + + if config.defaults[:daemon] + config.write_pid_file + else + config.log "Use CTRL-C to stop." + end + + config.log "Mongrel start up process completed." + config.join + + if config.needs_restart + if RUBY_PLATFORM !~ /mswin/ + cmd = "ruby #{__FILE__} start #{original_args.join(' ')}" + config.log "Restarting with arguments: #{cmd}" + config.stop + config.remove_pid_file + + if config.defaults[:daemon] + system cmd + else + STDERR.puts "Can't restart unless in daemon mode." + exit 1 + end + else + config.log "Win32 does not support restarts. Exiting." + end + end + end + + end + + class Stop < GemPlugin::Plugin "/commands" + include ::Ap4r::Mongrel::Command::Base + + def configure + options [ + ['-c', '--chdir PATH', "Change to dir", :@cwd, Dir.pwd], + ['-P', '--pid FILE', "PID file", :@pid_file, "log/mongrel_ap4r.pid"], + ['-f', '--force', "Force the shutdown (kill -9).", :@force, false], + ['-w', '--wait SECONDS', "Wait SECONDS before forcing shutdown", :@wait, "0"], + ] + end + + def validate + @cwd = File.expand_path(@cwd) + valid_dir? @cwd, "Path of chdir not valid: #@cwd " + Dir.chdir(@cwd) + + valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file" + + return @valid + end + + def run + if @force + @wait.to_i.times do |waiting| + exit(0) if not File.exist? @pid_file + sleep 1 + end + send_signal("KILL", @pid_file) if File.exist? @pid_file + else + send_signal("TERM", @pid_file) + end + end + end + + class Restart < GemPlugin::Plugin "/commands" + include ::Ap4r::Mongrel::Command::Base + + def configure + options [ + ['-c', '--chdir PATH', "Change to dir", :@cwd, Dir.pwd], + ['-P', '--pid FILE', "PID file", :@pid_file, "log/mongrel_ap4r.pid"], + ] + end + + def validate + @cwd = File.expand_path(@cwd) + valid_dir? @cwd, "Path of chdir not valid: #@cwd " + Dir.chdir(@cwd) + + valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file" + + return @valid + end + + def run + send_signal("USR2", @pid_file) + end + end + + # TODO: add Reload(reliable-msg) command class 2007/04/16 by shino + +end + + +def main(args) + cmd_name = args.shift + + begin + # TODO not all commands are implemented 2007/04/16 by shinohara + if %w(help version start stop restart reload).include? cmd_name + cmd_name = ::Ap4r::Mongrel::Command::PREFIX + cmd_name + end + + command = GemPlugin::Manager.instance.create("/commands/#{cmd_name}", :argv => args) + rescue OptionParser::InvalidOption + STDERR.puts "#$! for command '#{cmd_name}'" + STDERR.puts "Try #{cmd_name} -h to get help." + return false + rescue + STDERR.puts "ERROR RUNNING '#{cmd_name}': #$!" + STDERR.puts "Use help command to get help" + return false + end + + if not command.done_validating + if not command.validate + STDERR.puts "#{cmd_name} reported an error. Use mongrel_rails #{cmd_name} -h to get help." + return false + else + command.run + end + end + + return true +end + +# TODO: This script is not yet proper form of GemPlugin 2007/04/16 by shinohara +#GemPlugin::Manager.instance.load "ap4r" => GemPlugin::INCLUDE, "rails" => GemPlugin::EXCLUDE + +unless main(ARGV) + exit(1) +end Deleted: trunk/ap4r/script/mongrel_ap4r.rb =================================================================== --- trunk/ap4r/script/mongrel_ap4r.rb 2007-05-31 06:04:27 UTC (rev 217) +++ trunk/ap4r/script/mongrel_ap4r.rb 2007-05-31 06:27:17 UTC (rev 218) @@ -1,254 +0,0 @@ -# Author:: Shunichi Shinohara -# Copyright:: Copyright (c) 2007 Future Architect Corp. -# Licence:: MIT Licence - -require 'rubygems' -require 'mongrel' -require 'ap4r/mongrel' - -module Ap4r::Mongrel - - module Command - PREFIX = "ap4r::mongrel::" - - module Base - def self.included(klass) - return unless klass.kind_of?(Class) - klass.class_eval do |k| - include(::Mongrel::Command::Base) - end - # TODO: Can subclass the return of RubyGems::GemPlugin ? 2007/04/16 by shino - end - - # send a signal to the process specified by pid_file. - def send_signal(signal, pid_file) - pid = open(pid_file).read.to_i - print "Send signal #{signal} to AP4R at PID #{pid} ..." - begin - Process.kill(signal, pid) - rescue Errno::ESRCH - puts "Process not found." - end - puts "Done." - end - end - - end - - class Help < GemPlugin::Plugin "/commands" - include ::Ap4r::Mongrel::Command::Base - - def run - puts "Available AP4R commands are:\n\n" - Mongrel::Command::Registry.instance.commands.each do |name| - if name =~ /#{Command::PREFIX}/ - name = name[Command::PREFIX.length .. -1] - end - puts " - #{name[1 .. -1]}\n" - end - puts "\nfor further help, run each command with -h option to get help." - end - - end - - class Version < GemPlugin::Plugin "/commands" - include ::Ap4r::Mongrel::Command::Base - - def run - puts "AP4R Version is:" - puts - puts " - AP4R #{::Ap4r::VERSION::STRING}" - puts - end - - end - - class Start < GemPlugin::Plugin "/commands" - include ::Ap4r::Mongrel::Command::Base - - def configure - options [ - ["-d", "--daemonize", "Run in daemon mode", :@daemon, false], - ['-p', '--port PORT', "Port number used by mongrel", :@port, 7438], - ['-a', '--address HOST', "IP address used by mongrel", :@host, "0.0.0.0"], - ['-A', '--ap4r-config FILE', "Config file for reliable-msg/AP4R", :@ap4r_config_file, "config/queues.cfg"], - ['-l', '--log FILE', "Log file", :@log_file, "log/mongrel_ap4r.log"], - ['-P', '--pid FILE', "PID file", :@pid_file, "log/mongrel_ap4r.pid"], - ['-r', '--root PATH', "Document root (no meanings yet.)", :@docroot, "public"], - ['-c', '--chdir PATH', "Change to dir", :@cwd, Dir.pwd], - ] - end - - def validate - @cwd = File.expand_path(@cwd) - valid_dir? @cwd, "Path of chdir not valid: #@cwd " - Dir.chdir(@cwd) - - valid_dir? File.dirname(@log_file), "Path to log file not valid: #@log_file" - valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file" - valid_dir? @docroot, "Path to docroot not valid: #@docroot" - - return @valid - end - - def run - settings = { - :host => @host, :port => @port, - :log_file => @log_file, :pid_file => @pid_file, - :docroot => @docroot, - :daemon => @daemon, - :ap4r_config_file => @ap4r_config_file, - } - - config = ::Ap4r::Mongrel::Ap4rConfigurator.new(settings) do - if defaults[:daemon] - if File.exist? defaults[:pid_file] - log "PID file #{defaults[:pid_file]} exists!!! Exiting with error." - exit 1 - end - daemonize({:log_file => @log_file, :cwd => File.expand_path(".") }) - end - - listener do - log "Starting AP4R Handler with #{defaults[:ap4r_config_file]}" - uri "/", :handler => ::Ap4r::Mongrel::Ap4rHandler.new(defaults) - end - setup_signals(settings) - end - - config.run - config.log "Mongrel available at #{settings[:host]}:#{settings[:port]}" - - if config.defaults[:daemon] - config.write_pid_file - else - config.log "Use CTRL-C to stop." - end - - config.log "Mongrel start up process completed." - config.join - - if config.needs_restart - if RUBY_PLATFORM !~ /mswin/ - cmd = "ruby #{__FILE__} start #{original_args.join(' ')}" - config.log "Restarting with arguments: #{cmd}" - config.stop - config.remove_pid_file - - if config.defaults[:daemon] - system cmd - else - STDERR.puts "Can't restart unless in daemon mode." - exit 1 - end - else - config.log "Win32 does not support restarts. Exiting." - end - end - end - - end - - class Stop < GemPlugin::Plugin "/commands" - include ::Ap4r::Mongrel::Command::Base - - def configure - options [ - ['-c', '--chdir PATH', "Change to dir", :@cwd, Dir.pwd], - ['-P', '--pid FILE', "PID file", :@pid_file, "log/mongrel_ap4r.pid"], - ['-f', '--force', "Force the shutdown (kill -9).", :@force, false], - ['-w', '--wait SECONDS', "Wait SECONDS before forcing shutdown", :@wait, "0"], - ] - end - - def validate - @cwd = File.expand_path(@cwd) - valid_dir? @cwd, "Path of chdir not valid: #@cwd " - Dir.chdir(@cwd) - - valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file" - - return @valid - end - - def run - if @force - @wait.to_i.times do |waiting| - exit(0) if not File.exist? @pid_file - sleep 1 - end - send_signal("KILL", @pid_file) if File.exist? @pid_file - else - send_signal("TERM", @pid_file) - end - end - end - - class Restart < GemPlugin::Plugin "/commands" - include ::Ap4r::Mongrel::Command::Base - - def configure - options [ - ['-c', '--chdir PATH', "Change to dir", :@cwd, Dir.pwd], - ['-P', '--pid FILE', "PID file", :@pid_file, "log/mongrel_ap4r.pid"], - ] - end - - def validate - @cwd = File.expand_path(@cwd) - valid_dir? @cwd, "Path of chdir not valid: #@cwd " - Dir.chdir(@cwd) - - valid_dir? File.dirname(@pid_file), "Path to pid file not valid: #@pid_file" - - return @valid - end - - def run - send_signal("USR2", @pid_file) - end - end - - # TODO: add Reload(reliable-msg) command class 2007/04/16 by shino - -end - - -def main(args) - cmd_name = args.shift - - begin - # TODO not all commands are implemented 2007/04/16 by shinohara - if %w(help version start stop restart reload).include? cmd_name - cmd_name = ::Ap4r::Mongrel::Command::PREFIX + cmd_name - end - - command = GemPlugin::Manager.instance.create("/commands/#{cmd_name}", :argv => args) - rescue OptionParser::InvalidOption - STDERR.puts "#$! for command '#{cmd_name}'" - STDERR.puts "Try #{cmd_name} -h to get help." - return false - rescue - STDERR.puts "ERROR RUNNING '#{cmd_name}': #$!" - STDERR.puts "Use help command to get help" - return false - end - - if not command.done_validating - if not command.validate - STDERR.puts "#{cmd_name} reported an error. Use mongrel_rails #{cmd_name} -h to get help." - return false - else - command.run - end - end - - return true -end - -# TODO: This script is not yet proper form of GemPlugin 2007/04/16 by shinohara -#GemPlugin::Manager.instance.load "ap4r" => GemPlugin::INCLUDE, "rails" => GemPlugin::EXCLUDE - -unless main(ARGV) - exit(1) -end From shino at rubyforge.org Thu May 31 02:34:55 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 31 May 2007 02:34:55 -0400 (EDT) Subject: [ap4r-devel] [219] trunk/ap4r/script/mongrel_ap4r: make script thin Message-ID: <20070531063455.784B85240BAC@rubyforge.org> Revision: 219 Author: shino Date: 2007-05-31 02:34:55 -0400 (Thu, 31 May 2007) Log Message: ----------- make script thin Added Paths: ----------- trunk/ap4r/script/mongrel_ap4r Copied: trunk/ap4r/script/mongrel_ap4r (from rev 214, trunk/ap4r/script/start) =================================================================== --- trunk/ap4r/script/mongrel_ap4r (rev 0) +++ trunk/ap4r/script/mongrel_ap4r 2007-05-31 06:34:55 UTC (rev 219) @@ -0,0 +1,4 @@ +require 'rubygems' +require 'ap4r' + +load 'ap4r/mongrel_ap4r.rb' From shino at rubyforge.org Thu May 31 02:39:21 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 31 May 2007 02:39:21 -0400 (EDT) Subject: [ap4r-devel] [220] trunk/samples/HelloWorld/test/async: refactoring Message-ID: <20070531063921.7F87F5240BAC@rubyforge.org> Revision: 220 Author: shino Date: 2007-05-31 02:39:21 -0400 (Thu, 31 May 2007) Log Message: ----------- refactoring Modified Paths: -------------- trunk/samples/HelloWorld/test/async/ap4r_test_helper.rb trunk/samples/HelloWorld/test/async/hello_world_stories_test.rb Modified: trunk/samples/HelloWorld/test/async/ap4r_test_helper.rb =================================================================== --- trunk/samples/HelloWorld/test/async/ap4r_test_helper.rb 2007-05-31 06:34:55 UTC (rev 219) +++ trunk/samples/HelloWorld/test/async/ap4r_test_helper.rb 2007-05-31 06:39:21 UTC (rev 220) @@ -3,7 +3,7 @@ # Licence:: MIT Licence ENV["RAILS_ENV"] = "test" -require File.expand_path(File.dirname(__FILE__) + "/../../../config/environment") +require File.expand_path(File.dirname(__FILE__) + "/../../config/environment") require 'erb' require 'yaml' @@ -37,35 +37,66 @@ # Starts ap4r service. def start_ap4r_service(wait_until_started = true) - - command = "ruby #{@test_config["start_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " + + command = "ruby #{@test_config["start_ruby_args"]} #{@root_dir}/script/mongrel_ap4r " + "start -d -c #{@root_dir} -A #{@config_file}" - print "Starting AP4R with command: #{command} ..." - system(command) - print "and waiting..." - return unless wait_until_started - 50.times do - print "." - begin - if qm.alive? - puts "Done." - return - end - rescue => e - sleep 0.2 - end + message = "Starting Mongrel(AP4R)" + execute_command(command, message, false) + if wait_until_started + print "and waiting..." + wait_until_alive end + puts "Done." end # Stops ap4r service. def stop_ap4r_service - command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r.rb " + + command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r " + "stop -c #{@root_dir}" - puts "Terminating AP4R with command: #{command}." - system(command) + message = "Terminating Mongrel(AP4R)" + execute_command(command, message, false) @qm = nil end + # Starts rails service. + # Invokes mongrel_rails, so mongrel_rails should be installed. + def start_rails_service + # TODO: Can use script/server? It's more general. 2007/05/31 by shino + command = "mongrel_rails start -d --environment test" + message = "Starting Mongrel(Rails)" + execute_command(command, message) + end + + # Stops rails service. + def stop_rails_service + command = "mongrel_rails stop" + message = "Terminating Mongrel(Rails)" + execute_command(command, message, false) + end + + # Starts rails service and ap4r service. + # After block execution, stops both. + def with_services + begin + start_rails_service + begin + start_ap4r_service + yield + ensure + stop_ap4r_service + end + ensure + stop_rails_service + end + end + + def start_dispatchers + qm.dispatchers.start + end + + def stop_dispatchers + qm.dispatchers.stop + end + def clear(*queues) raise "not yet implemented" queues.each do |queue| @@ -76,22 +107,6 @@ end end - # Starts rails service and ap4r service. - # After block execution, stops both. -# def with_services -# begin -# start_rails_service -# begin -# start_ap4r_service -# yield -# ensure -# stop_ap4r_service -# end -# ensure -# stop_rails_service -# end -# end - def wait_for_saf_forward 50.times do count = ::Ap4r::StoredMessage.count(:conditions => {:status => ::Ap4r::StoredMessage::STATUS_STORED}) @@ -100,38 +115,36 @@ end end - # Starts rails service. - # Invokes mongrel_rails, so mongrel_rails should be installed. - def start_rails_service - print "Starting Mongrel(Rails)..." - system("mongrel_rails start -d --environment test") - puts "Done." + def wait_all_done + 50.times do + break if flag = qm.no_active_message? + sleep 0.2 + end end - # Stops rails service. - def stop_rails_service - system("mongrel_rails stop") + def dlq + qm.list :queue => "$dlq" end - def start_dispatchers - qm.dispatchers.start + private + def execute_command(command, message, with_done_message = true) + print "#{message} with command: #{command}..." + system(command) + puts "Done." if with_done_message end - def stop_dispatchers - qm.dispatchers.stop - end - - def wait_all_done + def wait_until_alive(message = nil) 50.times do - break if flag = qm.no_active_message? + print message if message + begin + break if qm.alive? + rescue => e + # ignore + end sleep 0.2 end end - def dlq - qm.list :queue => "$dlq" - end - end @@ -142,8 +155,11 @@ ap4r_test_helper.start_ap4r_service at_exit { ap4r_test_helper.stop_ap4r_service } +puts +at_exit { puts } + # Test::Unit also use at_exit hook, so load at the end -require "#{File.dirname(__FILE__)}/../../test_helper" +require "#{File.dirname(__FILE__)}/../test_helper" class Test::Unit::TestCase cattr_accessor :ap4r_helper @@ -152,9 +168,9 @@ @@ap4r_helper end -# def with_services(&block) -# ap4r_helper.with_services(&block) -# end + def with_services(&block) + ap4r_helper.with_services(&block) + end end Test::Unit::TestCase.ap4r_helper = ap4r_test_helper Modified: trunk/samples/HelloWorld/test/async/hello_world_stories_test.rb =================================================================== --- trunk/samples/HelloWorld/test/async/hello_world_stories_test.rb 2007-05-31 06:34:55 UTC (rev 219) +++ trunk/samples/HelloWorld/test/async/hello_world_stories_test.rb 2007-05-31 06:39:21 UTC (rev 220) @@ -2,41 +2,36 @@ require 'net/http' -# Trial implementation of test cases with ap4r integration. +# Test cases with ap4r integration. # some comments: -# - Subclassing IntegrationTest is adequate? # - Clearance of data in a database and queues should be included. -# - AP4R server can be running in process? -# - dispatcher control is needed for split assertions between (a)sync logics. # - Workspaces of ap4r and rails should have some conventions for convinience. # - Think about transition to RSpec. -# +# - HTTP session holding support is needed class HelloWorldStoriesTest < Test::Unit::TestCase def test_http_dispatch -# with_services do - ap4r_helper.stop_dispatchers - assert_one_line_added do - say_hello(:via => :http) - end - ap4r_helper.start_dispatchers - assert_one_line_added do - join_async_world - end -# end + ap4r_helper.stop_dispatchers + assert_one_line_added do + say_hello(:via => :http) + end + + ap4r_helper.start_dispatchers + assert_one_line_added do + join_async_world + end end def test_http_dispatch_with_saf -# with_services do - ap4r_helper.stop_dispatchers - assert_one_line_added do - say_hello(:with => :saf) - end - ap4r_helper.start_dispatchers - assert_one_line_added do - join_async_world - end -# end + ap4r_helper.stop_dispatchers + assert_one_line_added do + say_hello(:with => :saf) + end + + ap4r_helper.start_dispatchers + assert_one_line_added do + join_async_world + end end private @@ -64,10 +59,10 @@ `wc -l public/HelloWorld.txt`.to_i end - def assert_lines_added(delta) + def assert_lines_added(added_lines) initial = line_count yield - assert_equal (initial + delta), line_count + assert_equal (initial + added_lines), line_count end def assert_one_line_added(&block) From shino at rubyforge.org Thu May 31 02:43:22 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 31 May 2007 02:43:22 -0400 (EDT) Subject: [ap4r-devel] [221] trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/: remove direcotry not used now Message-ID: <20070531064322.6792F5240BAC@rubyforge.org> Revision: 221 Author: shino Date: 2007-05-31 02:43:22 -0400 (Thu, 31 May 2007) Log Message: ----------- remove direcotry not used now Removed Paths: ------------- trunk/samples/HelloWorld/test/integration/with_rails_and_ap4r/ From shino at rubyforge.org Thu May 31 02:46:20 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 31 May 2007 02:46:20 -0400 (EDT) Subject: [ap4r-devel] [222] trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/: remove trial integraition test directory. Message-ID: <20070531064621.ABFC55240BAC@rubyforge.org> Revision: 222 Author: shino Date: 2007-05-31 02:46:20 -0400 (Thu, 31 May 2007) Log Message: ----------- remove trial integraition test directory. This pattern (with AP4R server but without Rails server) is half-baked and not pormising, I think. Removed Paths: ------------- trunk/samples/HelloWorld/test/integration/with_ap4r_without_rails/ From shino at rubyforge.org Thu May 31 02:53:15 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 31 May 2007 02:53:15 -0400 (EDT) Subject: [ap4r-devel] [223] trunk/samples/HelloWorld/test/integration: move one of integration test trail patterns to integration test directory. Message-ID: <20070531065315.1C1255240BAC@rubyforge.org> Revision: 223 Author: shino Date: 2007-05-31 02:53:14 -0400 (Thu, 31 May 2007) Log Message: ----------- move one of integration test trail patterns to integration test directory. This tests (are intended to) run without AP4R server and without Rails server also. This pattern is well similar with original rails integration test. Plan is: - stubs queueing - makes async messages into get/post calls of rails' integration test. Added Paths: ----------- trunk/samples/HelloWorld/test/integration/ap4r_queue_stub.rb trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb Removed Paths: ------------- trunk/samples/HelloWorld/test/integration/just_inside_integration_test/ Copied: trunk/samples/HelloWorld/test/integration/ap4r_queue_stub.rb (from rev 220, trunk/samples/HelloWorld/test/integration/just_inside_integration_test/ap4r_queue_stub.rb) =================================================================== --- trunk/samples/HelloWorld/test/integration/ap4r_queue_stub.rb (rev 0) +++ trunk/samples/HelloWorld/test/integration/ap4r_queue_stub.rb 2007-05-31 06:53:14 UTC (rev 223) @@ -0,0 +1,42 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'reliable-msg' +require 'ap4r' + +class Ap4rTestHelper + + def clear(*queues) + end +end + +ap4r_test_helper = Ap4rTestHelper.new + +class ActionController::IntegrationTest + cattr_accessor :ap4r_helper + + def ap4r_helper + @@ap4r_helper + end +end + +ActionController::IntegrationTest.ap4r_helper = ap4r_test_helper + +module Ap4r + module AsyncHelper + module Base + def async_messages + @messages ||= [] + end + + private + def __queue_put(queue_name, queue_message, queue_headers) + async_messages << + {:queue_name => queue_name, + :message => queue_message, + :queue_headers => queue_headers} + end + end + end +end Copied: trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb (from rev 220, trunk/samples/HelloWorld/test/integration/just_inside_integration_test/hello_rails_integration_with_ap4r_test.rb) =================================================================== --- trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb (rev 0) +++ trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb 2007-05-31 06:53:14 UTC (rev 223) @@ -0,0 +1,23 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require "#{File.dirname(__FILE__)}/../../test_helper" +require "#{File.dirname(__FILE__)}/ap4r_queue_stub" + +# TODO: not yet implemented async call invocations 2007/05/29 by shino +class HelloRailsIntegrationWithAp4rTest < ActionController::IntegrationTest + + # Trivial test case to test the ap4r test helper. + def test_truth + assert true + assert_not_nil ap4r_helper + end + + def test_hello_via_http_and_async + get "/sync_hello/execute_via_http" + assert_equal 200, status + assert_equal 1, @controller.ap4r.async_messages.size + end + +end From shino at rubyforge.org Thu May 31 02:54:53 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 31 May 2007 02:54:53 -0400 (EDT) Subject: [ap4r-devel] [224] trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb: change file path Message-ID: <20070531065453.35F915240BAC@rubyforge.org> Revision: 224 Author: shino Date: 2007-05-31 02:54:52 -0400 (Thu, 31 May 2007) Log Message: ----------- change file path Modified Paths: -------------- trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb Modified: trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb =================================================================== --- trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb 2007-05-31 06:53:14 UTC (rev 223) +++ trunk/samples/HelloWorld/test/integration/hello_rails_integration_with_ap4r_test.rb 2007-05-31 06:54:52 UTC (rev 224) @@ -2,7 +2,7 @@ # Copyright:: Copyright (c) 2007 Future Architect Inc. # Licence:: MIT Licence -require "#{File.dirname(__FILE__)}/../../test_helper" +require "#{File.dirname(__FILE__)}/../test_helper" require "#{File.dirname(__FILE__)}/ap4r_queue_stub" # TODO: not yet implemented async call invocations 2007/05/29 by shino