From shino at rubyforge.org Wed Aug 1 20:39:30 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Wed, 1 Aug 2007 20:39:30 -0400 (EDT) Subject: [ap4r-devel] [247] trunk/ap4r/script: remove scripts only used in development time Message-ID: <20070802003930.646CD5240CCF@rubyforge.org> Revision: 247 Author: shino Date: 2007-08-01 20:39:29 -0400 (Wed, 01 Aug 2007) Log Message: ----------- remove scripts only used in development time Removed Paths: ------------- trunk/ap4r/script/loop.cmd trunk/ap4r/script/loop.rb Deleted: trunk/ap4r/script/loop.cmd =================================================================== --- trunk/ap4r/script/loop.cmd 2007-06-26 07:46:15 UTC (rev 246) +++ trunk/ap4r/script/loop.cmd 2007-08-02 00:39:29 UTC (rev 247) @@ -1,3 +0,0 @@ - at ECHO OFF - -ruby %~dp0loop.rb manager start -c queues%1.cfg Deleted: trunk/ap4r/script/loop.rb =================================================================== --- trunk/ap4r/script/loop.rb 2007-06-26 07:46:15 UTC (rev 246) +++ trunk/ap4r/script/loop.rb 2007-08-02 00:39:29 UTC (rev 247) @@ -1,8 +0,0 @@ -load_path = "-Ilib/" - -loop{ - puts; puts '=== queue manager starting ===' - system "ruby #{load_path} script/queues.rb #{ARGV.join(' ')}" - puts; puts '=== queue manager stopped ===' -} - From kato-k at rubyforge.org Mon Aug 6 05:33:31 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Mon, 6 Aug 2007 05:33:31 -0400 (EDT) Subject: [ap4r-devel] [248] trunk/ap4r: Added PostgreSQL support. Message-ID: <20070806093331.CC10A5240A7C@rubyforge.org> Revision: 248 Author: kato-k Date: 2007-08-06 05:33:28 -0400 (Mon, 06 Aug 2007) Log Message: ----------- Added PostgreSQL support. Modified Paths: -------------- trunk/ap4r/History.txt trunk/ap4r/lib/ap4r/message_store_ext.rb Added Paths: ----------- trunk/ap4r/config/queues_pgsql.cfg trunk/ap4r/lib/ap4r/postgresql.sql Modified: trunk/ap4r/History.txt =================================================================== --- trunk/ap4r/History.txt 2007-08-02 00:39:29 UTC (rev 247) +++ trunk/ap4r/History.txt 2007-08-06 09:33:28 UTC (rev 248) @@ -1,7 +1,8 @@ == 0.3.x === 0.3.3 (June ?, 2007) -* Added: support with hoe. +* Added: Support with hoe. +* Added: Support PostgreSQL as reliable RDBMS persistence. === 0.3.2 (June 7th, 2007) * Fixed: util/loc.rb doesn't work. Added: trunk/ap4r/config/queues_pgsql.cfg =================================================================== --- trunk/ap4r/config/queues_pgsql.cfg (rev 0) +++ trunk/ap4r/config/queues_pgsql.cfg 2007-08-06 09:33:28 UTC (rev 248) @@ -0,0 +1,19 @@ +--- +store: + type: postgresql + uri: # default is tcp://localhost:5432 + database: ap4r + username: ap4r + password: ap4r +drb: + host: + port: 6438 + acl: allow 127.0.0.1 allow ::1 allow 10.0.0.0/8 +dispatchers: + - + targets: queue.* + threads: 1 +#carriers: +# - +# source_uri: druby://another.host.local:6438 +# threads: 1 Modified: trunk/ap4r/lib/ap4r/message_store_ext.rb =================================================================== --- trunk/ap4r/lib/ap4r/message_store_ext.rb 2007-08-02 00:39:29 UTC (rev 247) +++ trunk/ap4r/lib/ap4r/message_store_ext.rb 2007-08-06 09:33:28 UTC (rev 248) @@ -33,6 +33,175 @@ end + begin + + # Make sure we have a MySQL library before creating this class, + # worst case we end up with a disk-based message store. Try the + # native MySQL library, followed by the Rails MySQL library. + begin + require 'postgres-pr/connection' + rescue LoadError + puts 'hoge' + end + + class PostgreSQL < Base #:nodoc: + + TYPE = self.name.split('::').last.downcase + + @@stores[TYPE] = self + + # Default prefix for tables in the database. + DEFAULT_PREFIX = 'reliable_msg_'; + + # Reference to an open PostgreSQL connection held in the current thread. + THREAD_CURRENT_PGSQL = :reliable_msg_pgsql #:nodoc: + + def initialize config, logger + super logger + @config = { :host=>config['host'], :username=>config['username'], :password=>config['password'], + :database=>config['database'], :port=>config['port'], :socket=>config['socket'] } + @prefix = config['prefix'] || DEFAULT_PREFIX + @queues_table = "#{@prefix}queues" + @topics_table = "#{@prefix}topics" + end + + def type + TYPE + end + + def setup + pgsql = connection + requires = 2 # Number of tables used by reliable-msg. + pgsql.query "\dt" do |result| + while row = result.fetch_row + requires -= 1 if row[0] == @queues_table || row[0] == @topics_table + end + end + if requires > 0 + sql = File.open File.join(File.dirname(__FILE__), "postgresql.sql"), "r" do |input| + input.readlines.join + end + sql.gsub! DEFAULT_PREFIX, @prefix + pgsql.query sql + true + end + end + + + def configuration + config = { "type"=>TYPE, "host"=>@config[:host], "username"=>@config[:username], + "password"=>@config[:password], "database"=>@config[:database] } + config["port"] = @config[:port] if @config[:port] + config["socket"] = @config[:socket] if @config[:socket] + config["prefix"] = @config[:prefix] if @config[:prefix] + config + end + + + def activate + super + load_index + end + + + def deactivate + Thread.list.each do |thread| + if conn = thread[THREAD_CURRENT_PGSQL] + thread[THREAD_CURRENT_PGSQL] = nil + conn.close + end + end + super + end + + + protected + + def update inserts, deletes, dlqs + pgsql = connection + pgsql.query "BEGIN" + begin + inserts.each do |insert| + if insert[:queue] + pgsql.query "INSERT INTO #{@queues_table} (id,queue,headers,object) VALUES('#{connection.quote insert[:id]}','#{connection.quote insert[:queue]}','#{connection.quote Marshal::dump(insert[:headers])}','#{connection.quote insert[:message]}')" +# pgsql.query "INSERT INTO #{@queues_table} (id,queue,headers,object) VALUES('#{connection.quote insert[:id]}','#{connection.quote insert[:queue]}',BINARY '#{connection.quote Marshal::dump(insert[:headers])}',BINARY '#{connection.quote insert[:message]}')" + else + pgsql.query "REPLACE #{@topics_table} (topic,headers,object) VALUES('#{connection.quote insert[:topic]}','#{connection.quote Marshal::dump(insert[:headers])}','#{connection.quote insert[:message]}')" + end + end + ids = deletes.inject([]) do |array, delete| + delete[:queue] ? array << "'#{delete[:id]}'" : array + end + if !ids.empty? + pgsql.query "DELETE FROM #{@queues_table} WHERE id IN (#{ids.join ','})" + end + dlqs.each do |dlq| + pgsql.query "UPDATE #{@queues_table} SET queue='#{Queue::DLQ}' WHERE id='#{connection.quote dlq[:id]}'" + end + pgsql.query "COMMIT" + rescue Exception=>error + pgsql.query "ROLLBACK" + raise error + end + super + end + + + def load_index + connection.query "SELECT id,queue,headers FROM #{@queues_table}" do |result| + while row = result.fetch_row + queue = @queues[row[1]] ||= [] + headers = Marshal::load row[2] + # Add element based on priority, higher priority comes first. + priority = headers[:priority] + added = false + queue.each_index do |idx| + if queue[idx][:priority] < priority + queue[idx, 0] = headers + added = true + break + end + end + queue << headers unless added + end + end + connection.query "SELECT topic,headers FROM #{@topics_table}" do |result| + while row = result.fetch_row + @topics[row[0]] = Marshal::load row[1] + end + end + end + + + def load id, type, queue_or_topic + message = nil + if type == :queue + connection.query "SELECT object FROM #{@queues_table} WHERE id='#{id}'" do |result| + message = if row = result.fetch_row + row[0] + end + end + else + connection.query "SELECT object FROM #{@topics_table} WHERE topic='#{queue_or_topic}'" do |result| + message = if row = result.fetch_row + row[0] + end + end + end + message + end + + def connection +# Thread.current[THREAD_CURRENT_PGSQL] ||= ::PostgresPR::Connection.new @config[:host], @config[:username], @config[:password], at config[:database], @config[:port], @config[:socket] + Thread.current[THREAD_CURRENT_PGSQL] ||= ::PostgresPR::Connection.new @config[:database], @config[:username], @config[:password], @config[:uri] + end + + end + + rescue LoadError + # do nothing + end + end end @@ -57,3 +226,21 @@ end end end + + +module PostgresPR + class Connection + def escape_string(str) + str.gsub(/([\0\n\r\032\'\"\\])/) do + case $1 + when "\0" then "\\0" + when "\n" then "\\n" + when "\r" then "\\r" + when "\032" then "\\Z" + else "\\"+$1 + end + end + end + alias :quote :escape_string + end +end Added: trunk/ap4r/lib/ap4r/postgresql.sql =================================================================== --- trunk/ap4r/lib/ap4r/postgresql.sql (rev 0) +++ trunk/ap4r/lib/ap4r/postgresql.sql 2007-08-06 09:33:28 UTC (rev 248) @@ -0,0 +1,13 @@ +CREATE TABLE reliable_msg_queues ( + id character varying(255) NOT NULL default '', + queue character varying(255) NOT NULL default '', + headers text NOT NULL, + object bytea NOT NULL, + PRIMARY KEY (id) +) +CREATE TABLE reliable_msg_topics ( + topic character varying(255) NOT NULL default '', + headers text NOT NULL, + object bytea NOT NULL, + PRIMARY KEY (topic) +) From kato-k at rubyforge.org Tue Aug 7 08:14:54 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Tue, 7 Aug 2007 08:14:54 -0400 (EDT) Subject: [ap4r-devel] [249] trunk/ap4r/lib/ap4r/message_store_ext.rb: Added: support two postgres module for Ruby, Ruby extention library and pure Ruby PostgreSQL interface. Message-ID: <20070807121454.39D545240AA0@rubyforge.org> Revision: 249 Author: kato-k Date: 2007-08-07 08:14:53 -0400 (Tue, 07 Aug 2007) Log Message: ----------- Added: support two postgres module for Ruby, Ruby extention library and pure Ruby PostgreSQL interface. Modified Paths: -------------- trunk/ap4r/lib/ap4r/message_store_ext.rb Modified: trunk/ap4r/lib/ap4r/message_store_ext.rb =================================================================== --- trunk/ap4r/lib/ap4r/message_store_ext.rb 2007-08-06 09:33:28 UTC (rev 248) +++ trunk/ap4r/lib/ap4r/message_store_ext.rb 2007-08-07 12:14:53 UTC (rev 249) @@ -35,13 +35,13 @@ begin - # Make sure we have a MySQL library before creating this class, + # Make sure we have a PostgreSQL library before creating this class, # worst case we end up with a disk-based message store. Try the - # native MySQL library, followed by the Rails MySQL library. - begin + # native PostgreSQL library, followed by the pure Ruby PostgreSQL library. + begin + require 'postgres' + rescue LoadError require 'postgres-pr/connection' - rescue LoadError - puts 'hoge' end class PostgreSQL < Base #:nodoc: @@ -193,7 +193,14 @@ def connection # Thread.current[THREAD_CURRENT_PGSQL] ||= ::PostgresPR::Connection.new @config[:host], @config[:username], @config[:password], at config[:database], @config[:port], @config[:socket] - Thread.current[THREAD_CURRENT_PGSQL] ||= ::PostgresPR::Connection.new @config[:database], @config[:username], @config[:password], @config[:uri] + + Thread.current[THREAD_CURRENT_PGSQL] ||= + if $:.any?{ |e| e.include?('postgres-pr') } + ::PostgresPR::Connection.new @config[:database], @config[:username], @config[:password], @config[:uri] + elsif $:.any?{ |e| e.include?('postgres')} + ::PGconn.connect @config[:host], @config[:port], @config[:options], @config[:tty], @config[:database], @config[:username], @config[:password] + end + end end @@ -205,6 +212,29 @@ end end +class PGconn + def quote str + PGconn.escape str + end +end + +module PostgresPR + class Connection + def escape_string(str) + str.gsub(/([\0\n\r\032\'\"\\])/) do + case $1 + when "\0" then "\\0" + when "\n" then "\\n" + when "\r" then "\\r" + when "\032" then "\\Z" + else "\\"+$1 + end + end + end + alias :quote :escape_string + end +end + if ReliableMsg::MessageStore::Base.use_mysql_extention class Mysql #:nodoc: alias original_query query @@ -226,21 +256,3 @@ end end end - - -module PostgresPR - class Connection - def escape_string(str) - str.gsub(/([\0\n\r\032\'\"\\])/) do - case $1 - when "\0" then "\\0" - when "\n" then "\\n" - when "\r" then "\\r" - when "\032" then "\\Z" - else "\\"+$1 - end - end - end - alias :quote :escape_string - end -end From kato-k at rubyforge.org Fri Aug 10 00:30:04 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 10 Aug 2007 00:30:04 -0400 (EDT) Subject: [ap4r-devel] [250] trunk/ap4r/lib/ap4r/message_store_ext.rb: Modified order of create connection to PostgreSQL, native library is first and pure ruby library is second. Message-ID: <20070810043004.76E1D5240E59@rubyforge.org> Revision: 250 Author: kato-k Date: 2007-08-10 00:30:04 -0400 (Fri, 10 Aug 2007) Log Message: ----------- Modified order of create connection to PostgreSQL, native library is first and pure ruby library is second. Modified Paths: -------------- trunk/ap4r/lib/ap4r/message_store_ext.rb Modified: trunk/ap4r/lib/ap4r/message_store_ext.rb =================================================================== --- trunk/ap4r/lib/ap4r/message_store_ext.rb 2007-08-07 12:14:53 UTC (rev 249) +++ trunk/ap4r/lib/ap4r/message_store_ext.rb 2007-08-10 04:30:04 UTC (rev 250) @@ -195,10 +195,10 @@ # Thread.current[THREAD_CURRENT_PGSQL] ||= ::PostgresPR::Connection.new @config[:host], @config[:username], @config[:password], at config[:database], @config[:port], @config[:socket] Thread.current[THREAD_CURRENT_PGSQL] ||= - if $:.any?{ |e| e.include?('postgres-pr') } + if $:.any?{ |e| e.include?('postgres') and not e.include?('postgres-pr') } + ::PGconn.connect @config[:host], @config[:port], @config[:options], @config[:tty], @config[:database], @config[:username], @config[:password] + elsif $:.any?{ |e| e.include?('postgres-pr')} ::PostgresPR::Connection.new @config[:database], @config[:username], @config[:password], @config[:uri] - elsif $:.any?{ |e| e.include?('postgres')} - ::PGconn.connect @config[:host], @config[:port], @config[:options], @config[:tty], @config[:database], @config[:username], @config[:password] end end From kato-k at rubyforge.org Fri Aug 10 02:46:34 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 10 Aug 2007 02:46:34 -0400 (EDT) Subject: [ap4r-devel] [251] trunk/ap4r/lib/ap4r/message_store_ext.rb: Refactoring: judgement of postgres library load. Message-ID: <20070810064634.66E375240E6C@rubyforge.org> Revision: 251 Author: kato-k Date: 2007-08-10 02:46:33 -0400 (Fri, 10 Aug 2007) Log Message: ----------- Refactoring: judgement of postgres library load. Modified Paths: -------------- trunk/ap4r/lib/ap4r/message_store_ext.rb Modified: trunk/ap4r/lib/ap4r/message_store_ext.rb =================================================================== --- trunk/ap4r/lib/ap4r/message_store_ext.rb 2007-08-10 04:30:04 UTC (rev 250) +++ trunk/ap4r/lib/ap4r/message_store_ext.rb 2007-08-10 06:46:33 UTC (rev 251) @@ -192,12 +192,11 @@ end def connection -# Thread.current[THREAD_CURRENT_PGSQL] ||= ::PostgresPR::Connection.new @config[:host], @config[:username], @config[:password], at config[:database], @config[:port], @config[:socket] - Thread.current[THREAD_CURRENT_PGSQL] ||= - if $:.any?{ |e| e.include?('postgres') and not e.include?('postgres-pr') } + # PGconn is overriding in this file, so is defined regardless of 'postgres' LoadError. + if Object.const_defined? :PGError ::PGconn.connect @config[:host], @config[:port], @config[:options], @config[:tty], @config[:database], @config[:username], @config[:password] - elsif $:.any?{ |e| e.include?('postgres-pr')} + elsif Object.const_defined? :PostgresPR ::PostgresPR::Connection.new @config[:database], @config[:username], @config[:password], @config[:uri] end From noreply at rubyforge.org Mon Aug 13 04:20:21 2007 From: noreply at rubyforge.org (noreply at rubyforge.org) Date: Mon, 13 Aug 2007 04:20:21 -0400 (EDT) Subject: [ap4r-devel] [Task #1593] reliable-msg's priority-aware dispatcher configuration Message-ID: <20070813082021.A958DA970004@rubyforge.org> Task #1593 has been updated. Project: AP4R Subproject: To Do Summary: reliable-msg's priority-aware dispatcher configuration Complete: 0% Status: Open Description: Dispathcers configuraion contains channel and # of threads so far. On the other hand, reliable-msg's selector can recognize :priority header. This feature is nice if dispatcher can also recognize. ------------------------------------------------------- For more info, visit: http://rubyforge.org/pm/task.php?func=detailtask&project_task_id=1593&group_id=1765&group_project_id=2144 From kato-k at rubyforge.org Thu Aug 23 09:27:19 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Thu, 23 Aug 2007 09:27:19 -0400 (EDT) Subject: [ap4r-devel] [253] branches/200709_gihyo/async_shop/as_rails: Experimental implementation for sync sample application. Message-ID: <20070823132719.88E7BA970020@rubyforge.org> Revision: 253 Author: kato-k Date: 2007-08-23 09:27:18 -0400 (Thu, 23 Aug 2007) Log Message: ----------- Experimental implementation for sync sample application. Added Paths: ----------- branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb branches/200709_gihyo/async_shop/as_rails/app/helpers/async_shop_helper.rb branches/200709_gihyo/async_shop/as_rails/app/models/order.rb branches/200709_gihyo/async_shop/as_rails/app/models/payment.rb branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/_form.rhtml branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml branches/200709_gihyo/async_shop/as_rails/db/migrate/ branches/200709_gihyo/async_shop/as_rails/db/migrate/001_create_orders.rb branches/200709_gihyo/async_shop/as_rails/db/migrate/002_create_payments.rb branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml branches/200709_gihyo/async_shop/as_rails/test/fixtures/payments.yml branches/200709_gihyo/async_shop/as_rails/test/functional/async_shop_controller_test.rb branches/200709_gihyo/async_shop/as_rails/test/unit/order_test.rb branches/200709_gihyo/async_shop/as_rails/test/unit/payment_test.rb branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/init.rb branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_client.rb branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/async_helper.rb branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/message_builder.rb Removed Paths: ------------- branches/200709_gihyo/async_shop/as_rails/log/development.log Added: branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,42 @@ +class AsyncShopController < ApplicationController + + def index + list + render :action => 'list' + end + + def list + @order_pages, @orders = paginate :orders, :per_page => 10 + end + + def new + @order = Order.new + end + + def order + begin + @order = Order.new(params[:order]) + @order.save + payment(@order[:id]) + + flash[:notice] = 'Order was successfully created.' + redirect_to :action => 'list' + rescue Error + render :action => 'new' + end + end + + def payment(order_id) + sleep 5 + + payment = Payment.new + payment.order_id = order_id + payment.save + end + + def destroy + Order.find(params[:id]).destroy + redirect_to :action => 'list' + end + +end Added: branches/200709_gihyo/async_shop/as_rails/app/helpers/async_shop_helper.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/helpers/async_shop_helper.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/app/helpers/async_shop_helper.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,2 @@ +module AsyncShopHelper +end Added: branches/200709_gihyo/async_shop/as_rails/app/models/order.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/models/order.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/app/models/order.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,2 @@ +class Order < ActiveRecord::Base +end Added: branches/200709_gihyo/async_shop/as_rails/app/models/payment.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/models/payment.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/app/models/payment.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,2 @@ +class Payment < ActiveRecord::Base +end Added: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/_form.rhtml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/_form.rhtml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/_form.rhtml 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,6 @@ +<%= error_messages_for 'order' %> + + +


+<%= text_field 'order', 'item' %>

+ Added: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,25 @@ +

Listing orders

+ + + + + + + +<% for order in @orders %> + + + + + + +<% end %> +
ItemOrdered atPayed at +
<%=h order.item %><%=h order.created_at %><%=h Payment.find(order.id).created_at %><%= link_to 'Destroy', { :action => 'destroy', :id => order }, :confirm => 'Are you sure?', :method => :post %>
+ +<%= link_to 'Previous page', { :page => @order_pages.current.previous } if @order_pages.current.previous %> +<%= link_to 'Next page', { :page => @order_pages.current.next } if @order_pages.current.next %> + +
+ +<%= link_to 'New order', :action => 'new' %> Added: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,8 @@ +

New order

+ +<% form_tag :action => 'order' do %> + <%= render :partial => 'form' %> + <%= submit_tag "Order" %> +<% end %> + +<%= link_to 'ordered list', :action => 'list' %> Added: branches/200709_gihyo/async_shop/as_rails/db/migrate/001_create_orders.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/db/migrate/001_create_orders.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/db/migrate/001_create_orders.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,13 @@ +class CreateOrders < ActiveRecord::Migration + def self.up + create_table :orders do |t| + t.column :customer_id, :integer + t.column :item, :string + t.column :created_at, :datetime + end + end + + def self.down + drop_table :orders + end +end Added: branches/200709_gihyo/async_shop/as_rails/db/migrate/002_create_payments.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/db/migrate/002_create_payments.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/db/migrate/002_create_payments.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,12 @@ +class CreatePayments < ActiveRecord::Migration + def self.up + create_table :payments do |t| + t.column :order_id, :integer + t.column :created_at, :datetime + end + end + + def self.down + drop_table :payments + end +end Deleted: branches/200709_gihyo/async_shop/as_rails/log/development.log =================================================================== Added: branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,11 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +one: + id: 1 + customer_id: 1 + item: MyString + orderd_at: 2007-08-23 +two: + id: 2 + customer_id: 1 + item: MyString + orderd_at: 2007-08-23 Added: branches/200709_gihyo/async_shop/as_rails/test/fixtures/payments.yml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/fixtures/payments.yml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/test/fixtures/payments.yml 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,9 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +one: + id: 1 + order_id: 1 + payed_at: 2007-08-23 +two: + id: 2 + order_id: 1 + payed_at: 2007-08-23 Added: branches/200709_gihyo/async_shop/as_rails/test/functional/async_shop_controller_test.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/functional/async_shop_controller_test.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/test/functional/async_shop_controller_test.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,18 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'async_shop_controller' + +# Re-raise errors caught by the controller. +class AsyncShopController; def rescue_action(e) raise e end; end + +class AsyncShopControllerTest < Test::Unit::TestCase + def setup + @controller = AsyncShopController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + # Replace this with your real tests. + def test_truth + assert true + end +end Added: branches/200709_gihyo/async_shop/as_rails/test/unit/order_test.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/unit/order_test.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/test/unit/order_test.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,10 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class OrderTest < Test::Unit::TestCase + fixtures :orders + + # Replace this with your real tests. + def test_truth + assert true + end +end Added: branches/200709_gihyo/async_shop/as_rails/test/unit/payment_test.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/unit/payment_test.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/test/unit/payment_test.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,10 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class PaymentTest < Test::Unit::TestCase + fixtures :payments + + # Replace this with your real tests. + def test_truth + assert true + end +end Added: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/init.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/init.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/init.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,11 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'ap4r_client' + +class ActionController::Base + def ap4r + @ap4r_client ||= ::Ap4r::Client.new(self) + end +end Added: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_client.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_client.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,132 @@ +# Author:: Kiwamu Kato +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'forwardable' +require 'async_helper' + +module Ap4r #:nodoc: + + # This +Client+ 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"}) + # ap4r.async_to({:controller => 'async_world', :action => 'execute'}, + # {:world_id => 1, :message => "World"}, + # {:dispatch_mode => :HTTP}) # skippable + # + # render :action => 'response' + # + # Complement: Above +ap4r+ method is defiend init.rb in +%RAILS_ROOT%/vendor/plugin/ap4r/+. + # + class Client + extend Forwardable + include ::Ap4r::AsyncHelper::Base + + def initialize controller + @controller = controller + end + + def_delegators :@controller, :logger, :url_for + + # 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. + # + # Examples: the most simple + # + # ap4r.async_to({:controller => 'next_controller', :action => 'next_action'}, + # {:world_id => 1, :message => "World"}) + # + # + # Examples: taking block + # + # ap4r.async_to({:controller => 'next_controller', :action => 'next_action'}) do + # body :world_id, 1 + # body :message, "World" + # end + # + # + # Examples: transmitting ActiveRecord object + # + # ap4r.async_to({: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). + # + # ap4r.async_to({: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 + # + # ap4r.async_to({:controller => 'next_controller', :action => 'next_action'}) do + # world = World.find(1).to_xml :except => ... + # body_as_xml world + # end + # + # + # Examples: setting message header + # + # ap4r.async_to({:controller => 'next_controller', :action => 'next_action'}) do + # body :world_id, 1 + # body :message, "World" + # + # header :priority, 1 + # http_header "Content-type", ... + # end + # + alias :async_to :async_dispatch + + # Provides at-least-once QoS level. + # +block+ are tipically composed of database accesses and +async_to+ calls. + # Database accesses are executed transactionallly by +active_record_class+'s transaction method. + # In the +block+, +async_to+ 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_to method in this block. + # + # ap4r.transaction do + # req = WorldRequest.new([:world_id => 1, :message => "World"}) + # ap4r.async_to({:controller => 'async_world', :action => 'execute'}, + # {:world_id => 1, :message => "World"}) + # + # render :action => 'response' + # end + # + alias :transaction :transaction_with_saf + + end +end Added: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/async_helper.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/async_helper.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,262 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'reliable-msg' +require 'ap4r/stored_message' +require 'message_builder' + +module Ap4r + + # This +AsyncHelper+ is included to +Ap4rClient+ and works the Rails plugin + # for asynchronous processing. + # + 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 + + # This method is aliased as ::Ap4r::Client#transaction + # + 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 + + # This method is aliased as ::Ap4r::Client#async_to + # + def async_dispatch(url_options = {}, async_params = {}, rm_options = {}, &block) + + 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] ||= @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. + # 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 + + message_builder = ::Ap4r::MessageBuilder.new(queue_name, queue_message, queue_headers) + if block_given? + message_builder.instance_eval(&block) + end + queue_name = message_builder.queue_name + 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, 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 __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) + 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 + + 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) + return url_for_options if url_for_options.kind_of?(String) + @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[:url]) + @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[:url][:action] + action_method_name.camelcase + end + + def options_without_action + @url_options[:url].reject{ |k,v| k == :action } + 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: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/message_builder.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/message_builder.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/message_builder.rb 2007-08-23 13:27:18 UTC (rev 253) @@ -0,0 +1,181 @@ +# Author:: Kiwamu Kato +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'active_record' + +module Ap4r #:nodoc: + + # 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 + @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, :message_body, :message_headers + attr_reader :format, :to_xml_options + + # Sets message body in async_to block. + # The first argument is key and the second one is value. + # + # options are for to_xml conversion on Array and Hash, ActiveRecord objects. + # + def body(k, v, options = { }) + k ||= v.class + if v.kind_of? ActiveRecord::Base + @message_body[k.to_sym] = v + @to_xml_options = @to_xml_options.merge(options) + else + @message_body[k.to_sym] = v + end + end + + # Sets message header in async_to block. + # The first argument is key and the second one is value. + # + # Now supports following keys: + # :expire + # :priority + # :delivery + # :max_deliveries + # :dispatch_mode + # :target_method + # :target_url + # :id + # + # For details, please refer the reliable-msg. + # + def header(k, v) + @message_headers[k.to_sym] = v + end + + # Sets http header in async_to block such as 'Content_type'. + # The first argument is key and the second one is value. + # + def http_header(k, v) + @message_headers["http_header_#{k}".to_sym] = v + end + + # Sets format message serialization. + # As to the format, automatically sets content-type. + # Unless any format, content-type is defined as "application/x-www-form-urlencoded". + # + 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 + + # Sets text format message. No need to use +format+. + # + def body_as_text(text) + @message_body_with_format = text + format :text + end + + # Sets xml format message. No need to use +format+. + # + def body_as_xml(xml) + @message_body_with_format = xml + format :xml + end + + # Sets json format message. No need to use +format+. + # + def body_as_json(json) + @message_body_with_format = json + format :json + end + + # Sets yaml format message. No need to use +format+. + # + def body_as_yaml(yaml) + @message_body_with_format = yaml + format :yaml + end + + # Return converted message body, as to assigned format. + # + 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 @message_body.to_xml @to_xml_options + when :json + return @message_body.to_json + when :yaml + return @message_body.to_yaml + else + @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 + + private + def query_string(hash) + build_query_string(hash, nil, nil) + end + + 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 + + def set_content_type(type) + http_header("Content-type", type) + end + end +end From kato-k at rubyforge.org Thu Aug 23 21:47:12 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Thu, 23 Aug 2007 21:47:12 -0400 (EDT) Subject: [ap4r-devel] [254] branches/200709_gihyo/async_shop/as_rails: Modified: views and temporally removed plugin. Message-ID: <20070824014712.EC3ED5240CF0@rubyforge.org> Revision: 254 Author: kato-k Date: 2007-08-23 21:47:11 -0400 (Thu, 23 Aug 2007) Log Message: ----------- Modified: views and temporally removed plugin. Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml Removed Paths: ------------- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/_form.rhtml branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/ Deleted: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/_form.rhtml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/_form.rhtml 2007-08-23 13:27:18 UTC (rev 253) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/_form.rhtml 2007-08-24 01:47:11 UTC (rev 254) @@ -1,6 +0,0 @@ -<%= error_messages_for 'order' %> - - -


-<%= text_field 'order', 'item' %>

- Modified: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml 2007-08-23 13:27:18 UTC (rev 253) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml 2007-08-24 01:47:11 UTC (rev 254) @@ -1,7 +1,9 @@

New order

<% form_tag :action => 'order' do %> - <%= render :partial => 'form' %> + <%= error_messages_for 'order' %> +


+ <%= text_field 'order', 'item' %>

<%= submit_tag "Order" %> <% end %> From kato-k at rubyforge.org Fri Aug 24 01:44:46 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 24 Aug 2007 01:44:46 -0400 (EDT) Subject: [ap4r-devel] [255] branches/200709_gihyo/async_shop/as_rails: Modified: ActiveRecord transaction and flash notice. Message-ID: <20070824054446.A31985240E35@rubyforge.org> Revision: 255 Author: kato-k Date: 2007-08-24 01:44:45 -0400 (Fri, 24 Aug 2007) Log Message: ----------- Modified: ActiveRecord transaction and flash notice. Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml Added Paths: ----------- branches/200709_gihyo/async_shop/as_rails/app/views/layouts/async_shop.rhtml branches/200709_gihyo/async_shop/as_rails/public/stylesheets/scaffold.css Modified: branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-24 01:47:11 UTC (rev 254) +++ branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-24 05:44:45 UTC (rev 255) @@ -15,13 +15,17 @@ def order begin - @order = Order.new(params[:order]) - @order.save - payment(@order[:id]) + ActiveRecord::Base.transaction do + @order = Order.new(params[:order]) + @order.save + raise Exception + payment(@order[:id]) - flash[:notice] = 'Order was successfully created.' - redirect_to :action => 'list' - rescue Error + flash[:notice] = 'Order was successfully created.' + redirect_to :action => 'list' + end + rescue Exception + flash[:notice] = 'Order was failed.' render :action => 'new' end end Modified: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-24 01:47:11 UTC (rev 254) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-24 05:44:45 UTC (rev 255) @@ -11,7 +11,7 @@ <%=h order.item %> <%=h order.created_at %> - <%=h Payment.find(order.id).created_at %> + <%=h begin Payment.find(order.id).created_at rescue "not yet." end %> <%= link_to 'Destroy', { :action => 'destroy', :id => order }, :confirm => 'Are you sure?', :method => :post %> <% end %> Added: branches/200709_gihyo/async_shop/as_rails/app/views/layouts/async_shop.rhtml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/layouts/async_shop.rhtml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/app/views/layouts/async_shop.rhtml 2007-08-24 05:44:45 UTC (rev 255) @@ -0,0 +1,17 @@ + + + + + + AsyncShop: <%= controller.action_name %> + <%= stylesheet_link_tag 'scaffold' %> + + + +

<%= flash[:notice] %>

+ +<%= yield %> + + + Added: branches/200709_gihyo/async_shop/as_rails/public/stylesheets/scaffold.css =================================================================== --- branches/200709_gihyo/async_shop/as_rails/public/stylesheets/scaffold.css (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/public/stylesheets/scaffold.css 2007-08-24 05:44:45 UTC (rev 255) @@ -0,0 +1,74 @@ +body { background-color: #fff; color: #333; } + +body, p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; +} + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; +} + +a { color: #000; } +a:visited { color: #666; } +a:hover { color: #fff; background-color:#000; } + +.fieldWithErrors { + padding: 2px; + background-color: red; + display: table; +} + +#errorExplanation { + width: 400px; + border: 2px solid red; + padding: 7px; + padding-bottom: 12px; + margin-bottom: 20px; + background-color: #f0f0f0; +} + +#errorExplanation h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + background-color: #c00; + color: #fff; +} + +#errorExplanation p { + color: #333; + margin-bottom: 0; + padding: 5px; +} + +#errorExplanation ul li { + font-size: 12px; + list-style: square; +} + +div.uploadStatus { + margin: 5px; +} + +div.progressBar { + margin: 5px; +} + +div.progressBar div.border { + background-color: #fff; + border: 1px solid grey; + width: 100%; +} + +div.progressBar div.background { + background-color: #333; + height: 18px; + width: 0%; +} + From kato-k at rubyforge.org Fri Aug 24 03:11:18 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 24 Aug 2007 03:11:18 -0400 (EDT) Subject: [ap4r-devel] [256] branches/200709_gihyo/async_shop/as_rails/app: Fixed: trivial bugs. Message-ID: <20070824071118.93D685240E99@rubyforge.org> Revision: 256 Author: kato-k Date: 2007-08-24 03:11:18 -0400 (Fri, 24 Aug 2007) Log Message: ----------- Fixed: trivial bugs. Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml Modified: branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-24 05:44:45 UTC (rev 255) +++ branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-24 07:11:18 UTC (rev 256) @@ -18,7 +18,6 @@ ActiveRecord::Base.transaction do @order = Order.new(params[:order]) @order.save - raise Exception payment(@order[:id]) flash[:notice] = 'Order was successfully created.' Modified: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-24 05:44:45 UTC (rev 255) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-24 07:11:18 UTC (rev 256) @@ -6,19 +6,19 @@ Ordered at Payed at - + <% for order in @orders %> <%=h order.item %> <%=h order.created_at %> - <%=h begin Payment.find(order.id).created_at rescue "not yet." end %> + <%=h begin Payment.find_by_order_id(order.id).created_at rescue "not yet." end %> <%= link_to 'Destroy', { :action => 'destroy', :id => order }, :confirm => 'Are you sure?', :method => :post %> <% end %> <%= link_to 'Previous page', { :page => @order_pages.current.previous } if @order_pages.current.previous %> -<%= link_to 'Next page', { :page => @order_pages.current.next } if @order_pages.current.next %> +<%= link_to 'Next page', { :page => @order_pages.current.next } if @order_pages.current.next %>
From kato-k at rubyforge.org Fri Aug 24 03:28:59 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 24 Aug 2007 03:28:59 -0400 (EDT) Subject: [ap4r-devel] [257] branches/200709_gihyo/async_shop/as_ap4r/: Removed: ap4r directory temporally. Message-ID: <20070824072859.A50405240EF0@rubyforge.org> Revision: 257 Author: kato-k Date: 2007-08-24 03:28:59 -0400 (Fri, 24 Aug 2007) Log Message: ----------- Removed: ap4r directory temporally. Removed Paths: ------------- branches/200709_gihyo/async_shop/as_ap4r/ From kato-k at rubyforge.org Fri Aug 24 03:32:32 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 24 Aug 2007 03:32:32 -0400 (EDT) Subject: [ap4r-devel] [258] tags/200709_gihyo_sync_shop/: tag 200709_gihyo_sync_shop Message-ID: <20070824073232.C62A25240F22@rubyforge.org> Revision: 258 Author: kato-k Date: 2007-08-24 03:32:32 -0400 (Fri, 24 Aug 2007) Log Message: ----------- tag 200709_gihyo_sync_shop Added Paths: ----------- tags/200709_gihyo_sync_shop/ Copied: tags/200709_gihyo_sync_shop (from rev 257, branches/200709_gihyo/async_shop) From kato-k at rubyforge.org Fri Aug 24 03:58:13 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 24 Aug 2007 03:58:13 -0400 (EDT) Subject: [ap4r-devel] [259] trunk/ap4r/config/queues_mysql.cfg: Modified: default configuratin for access control list. Message-ID: <20070824075813.384055240F04@rubyforge.org> Revision: 259 Author: kato-k Date: 2007-08-24 03:58:12 -0400 (Fri, 24 Aug 2007) Log Message: ----------- Modified: default configuratin for access control list. Modified Paths: -------------- trunk/ap4r/config/queues_mysql.cfg Modified: trunk/ap4r/config/queues_mysql.cfg =================================================================== --- trunk/ap4r/config/queues_mysql.cfg 2007-08-24 07:32:32 UTC (rev 258) +++ trunk/ap4r/config/queues_mysql.cfg 2007-08-24 07:58:12 UTC (rev 259) @@ -8,7 +8,7 @@ drb: host: port: 6438 - acl: allow 127.0.0.1 allow 10.0.0.0/8 + acl: allow 127.0.0.1 allow ::1 allow 10.0.0.0/8 dispatchers: - targets: queue.* @@ -16,4 +16,4 @@ #carriers: # - # source_uri: druby://another.host.local:6438 -# threads: 1 \ No newline at end of file +# threads: 1 From kato-k at rubyforge.org Fri Aug 24 05:31:35 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 24 Aug 2007 05:31:35 -0400 (EDT) Subject: [ap4r-devel] [260] branches/200709_gihyo/async_shop: Modified: asynchronization. Message-ID: <20070824093135.AD53C5240A50@rubyforge.org> Revision: 260 Author: kato-k Date: 2007-08-24 05:31:34 -0400 (Fri, 24 Aug 2007) Log Message: ----------- Modified: asynchronization. Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb Added Paths: ----------- branches/200709_gihyo/async_shop/as_ap4r/ branches/200709_gihyo/async_shop/as_ap4r/config/ branches/200709_gihyo/async_shop/as_ap4r/config/ap4r_settings.rb branches/200709_gihyo/async_shop/as_ap4r/config/log4r.yaml branches/200709_gihyo/async_shop/as_ap4r/config/queues.cfg branches/200709_gihyo/async_shop/as_ap4r/config/queues_disk.cfg branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg branches/200709_gihyo/async_shop/as_ap4r/log/ branches/200709_gihyo/async_shop/as_ap4r/public/ branches/200709_gihyo/async_shop/as_ap4r/script/ branches/200709_gihyo/async_shop/as_ap4r/script/irm branches/200709_gihyo/async_shop/as_ap4r/script/loop.cmd branches/200709_gihyo/async_shop/as_ap4r/script/loop.rb branches/200709_gihyo/async_shop/as_ap4r/script/mongrel_ap4r branches/200709_gihyo/async_shop/as_ap4r/script/start branches/200709_gihyo/async_shop/as_ap4r/script/stop branches/200709_gihyo/async_shop/as_ap4r/tmp/ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/init.rb branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_client.rb branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/async_helper.rb branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/message_builder.rb Added: branches/200709_gihyo/async_shop/as_ap4r/config/ap4r_settings.rb =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/config/ap4r_settings.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/config/ap4r_settings.rb 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,5 @@ +Ap4r::Configuration.setup {|services| + services.add 'queues_disk.cfg', :host => 'localhost', :name => :rm1 +# services.add 'queues.cfg', :name => :rm2 +} + Added: branches/200709_gihyo/async_shop/as_ap4r/config/log4r.yaml =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/config/log4r.yaml (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/config/log4r.yaml 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,61 @@ +purpose : Test +description: This is the YAML doc + this yaml has many many unnecessary setting + for testing/explanation only. + edit properly for normal use. + +--- + +log4r_config: + # define all pre config ... + pre_config: + global: + level: DEBUG + root : + level: DEBUG + parameters: + - name : x + value : aaa + - name : y + value : bbb + + # define all loggers ... + loggers: + - name : qm_logger + level : DEBUG + additive : 'false' + trace : 'false' + outputters: + - stderr + - logfile + + - name : yourlogger #not used yet... + level : INFO + outputters: + - stderr + - logfile + + # define all outputters (incl. formatters) + outputters: + - type : StderrOutputter + name : stderr + level : DEBUG + only_at : + - INFO + - WARN + - FATAL + formatter: + date_pattern: '%y%m%d %H:%M:%S' + pattern : '%d %l: %m ' + type : PatternFormatter + + - type : DateFileOutputter + name : logfile + level : DEBUG + date_pattern: '%Y%m%d' + trunc : 'false' + dirname : "#{HOME}/logs" + formatter : + date_pattern: '%y%m%d %H:%M:%S' + pattern : '%d %l: %m' + type : PatternFormatter Added: branches/200709_gihyo/async_shop/as_ap4r/config/queues.cfg =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/config/queues.cfg (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/config/queues.cfg 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,20 @@ +--- +store: + type: mysql + host: localhost + database: test + username: test + password: +drb: + host: + port: 6438 + acl: allow 127.0.0.1 +dispatchers: + - + targets: queue.* + threads: 1 +#carriers: +# - +# source_uri: druby://another.host.local:6438 +# threads: 1 + Added: branches/200709_gihyo/async_shop/as_ap4r/config/queues_disk.cfg =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/config/queues_disk.cfg (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/config/queues_disk.cfg 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,15 @@ +--- +store: + type: disk +drb: + host: + port: 6438 + acl: allow 127.0.0.1 allow ::1 allow 10.0.0.0/8 +dispatchers: + - + targets: queue.* + threads: 1 +#carriers: +# - +# source_uri: druby://another.host.local:6438 +# threads: 1 Added: branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,19 @@ +--- +store: + type: mysql + host: localhost + database: ap4r + username: ap4r + password: ap4r +drb: + host: + port: 6438 + acl: allow 127.0.0.1 allow 10.0.0.0/8 allow ::1 +dispatchers: + - + targets: queue.* + threads: 1 +#carriers: +# - +# source_uri: druby://another.host.local:6438 +# threads: 1 Added: branches/200709_gihyo/async_shop/as_ap4r/script/irm =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/script/irm (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/script/irm 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,4 @@ +require 'rubygems' +require 'ap4r' + +require 'ap4r/util/irm' Added: branches/200709_gihyo/async_shop/as_ap4r/script/loop.cmd =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/script/loop.cmd (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/script/loop.cmd 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,3 @@ + at ECHO OFF + +ruby %~dp0loop.rb manager start -c queues%1.cfg Added: branches/200709_gihyo/async_shop/as_ap4r/script/loop.rb =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/script/loop.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/script/loop.rb 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,8 @@ +load_path = "-Ilib/" + +loop{ + puts; puts '=== queue manager starting ===' + system "ruby #{load_path} script/queues.rb #{ARGV.join(' ')}" + puts; puts '=== queue manager stopped ===' +} + Added: branches/200709_gihyo/async_shop/as_ap4r/script/mongrel_ap4r =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/script/mongrel_ap4r (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/script/mongrel_ap4r 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,4 @@ +require 'rubygems' +require 'ap4r' + +load 'ap4r/mongrel_ap4r.rb' Added: branches/200709_gihyo/async_shop/as_ap4r/script/start =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/script/start (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/script/start 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,5 @@ +require 'rubygems' +require 'ap4r/script/setup' + +require 'ap4r/script/queue_manager_control' +Ap4r::Script::QueueManagerControl.new.start(ARGV) Added: branches/200709_gihyo/async_shop/as_ap4r/script/stop =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/script/stop (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/script/stop 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1 @@ + Modified: branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-24 07:58:12 UTC (rev 259) +++ branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-24 09:31:34 UTC (rev 260) @@ -18,8 +18,10 @@ ActiveRecord::Base.transaction do @order = Order.new(params[:order]) @order.save - payment(@order[:id]) + ap4r.async_to({:action => 'payment'}, + {:order_id => @order.id}) + flash[:notice] = 'Order was successfully created.' redirect_to :action => 'list' end @@ -29,12 +31,13 @@ end end - def payment(order_id) + def payment sleep 5 payment = Payment.new - payment.order_id = order_id + payment.order_id = params[:order_id] payment.save + render :text => "true" end def destroy Added: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/init.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/init.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/init.rb 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,11 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'ap4r_client' + +class ActionController::Base + def ap4r + @ap4r_client ||= ::Ap4r::Client.new(self) + end +end Added: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_client.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_client.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_client.rb 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,132 @@ +# Author:: Kiwamu Kato +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'forwardable' +require 'async_helper' + +module Ap4r #:nodoc: + + # This +Client+ 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"}) + # ap4r.async_to({:controller => 'async_world', :action => 'execute'}, + # {:world_id => 1, :message => "World"}, + # {:dispatch_mode => :HTTP}) # skippable + # + # render :action => 'response' + # + # Complement: Above +ap4r+ method is defiend init.rb in +%RAILS_ROOT%/vendor/plugin/ap4r/+. + # + class Client + extend Forwardable + include ::Ap4r::AsyncHelper::Base + + def initialize controller + @controller = controller + end + + def_delegators :@controller, :logger, :url_for + + # 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. + # + # Examples: the most simple + # + # ap4r.async_to({:controller => 'next_controller', :action => 'next_action'}, + # {:world_id => 1, :message => "World"}) + # + # + # Examples: taking block + # + # ap4r.async_to({:controller => 'next_controller', :action => 'next_action'}) do + # body :world_id, 1 + # body :message, "World" + # end + # + # + # Examples: transmitting ActiveRecord object + # + # ap4r.async_to({: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). + # + # ap4r.async_to({: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 + # + # ap4r.async_to({:controller => 'next_controller', :action => 'next_action'}) do + # world = World.find(1).to_xml :except => ... + # body_as_xml world + # end + # + # + # Examples: setting message header + # + # ap4r.async_to({:controller => 'next_controller', :action => 'next_action'}) do + # body :world_id, 1 + # body :message, "World" + # + # header :priority, 1 + # http_header "Content-type", ... + # end + # + alias :async_to :async_dispatch + + # Provides at-least-once QoS level. + # +block+ are tipically composed of database accesses and +async_to+ calls. + # Database accesses are executed transactionallly by +active_record_class+'s transaction method. + # In the +block+, +async_to+ 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_to method in this block. + # + # ap4r.transaction do + # req = WorldRequest.new([:world_id => 1, :message => "World"}) + # ap4r.async_to({:controller => 'async_world', :action => 'execute'}, + # {:world_id => 1, :message => "World"}) + # + # render :action => 'response' + # end + # + alias :transaction :transaction_with_saf + + end +end Added: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/async_helper.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/async_helper.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/async_helper.rb 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,262 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'reliable-msg' +require 'ap4r/stored_message' +require 'message_builder' + +module Ap4r + + # This +AsyncHelper+ is included to +Ap4rClient+ and works the Rails plugin + # for asynchronous processing. + # + 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 + + # This method is aliased as ::Ap4r::Client#transaction + # + 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 + + # This method is aliased as ::Ap4r::Client#async_to + # + def async_dispatch(url_options = {}, async_params = {}, rm_options = {}, &block) + + 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] ||= @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. + # 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 + + message_builder = ::Ap4r::MessageBuilder.new(queue_name, queue_message, queue_headers) + if block_given? + message_builder.instance_eval(&block) + end + queue_name = message_builder.queue_name + 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, 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 __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) + 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 + + 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) + return url_for_options if url_for_options.kind_of?(String) + @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[:url]) + @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[:url][:action] + action_method_name.camelcase + end + + def options_without_action + @url_options[:url].reject{ |k,v| k == :action } + 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: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/message_builder.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/message_builder.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/message_builder.rb 2007-08-24 09:31:34 UTC (rev 260) @@ -0,0 +1,181 @@ +# Author:: Kiwamu Kato +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +require 'active_record' + +module Ap4r #:nodoc: + + # 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 + @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, :message_body, :message_headers + attr_reader :format, :to_xml_options + + # Sets message body in async_to block. + # The first argument is key and the second one is value. + # + # options are for to_xml conversion on Array and Hash, ActiveRecord objects. + # + def body(k, v, options = { }) + k ||= v.class + if v.kind_of? ActiveRecord::Base + @message_body[k.to_sym] = v + @to_xml_options = @to_xml_options.merge(options) + else + @message_body[k.to_sym] = v + end + end + + # Sets message header in async_to block. + # The first argument is key and the second one is value. + # + # Now supports following keys: + # :expire + # :priority + # :delivery + # :max_deliveries + # :dispatch_mode + # :target_method + # :target_url + # :id + # + # For details, please refer the reliable-msg. + # + def header(k, v) + @message_headers[k.to_sym] = v + end + + # Sets http header in async_to block such as 'Content_type'. + # The first argument is key and the second one is value. + # + def http_header(k, v) + @message_headers["http_header_#{k}".to_sym] = v + end + + # Sets format message serialization. + # As to the format, automatically sets content-type. + # Unless any format, content-type is defined as "application/x-www-form-urlencoded". + # + 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 + + # Sets text format message. No need to use +format+. + # + def body_as_text(text) + @message_body_with_format = text + format :text + end + + # Sets xml format message. No need to use +format+. + # + def body_as_xml(xml) + @message_body_with_format = xml + format :xml + end + + # Sets json format message. No need to use +format+. + # + def body_as_json(json) + @message_body_with_format = json + format :json + end + + # Sets yaml format message. No need to use +format+. + # + def body_as_yaml(yaml) + @message_body_with_format = yaml + format :yaml + end + + # Return converted message body, as to assigned format. + # + 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 @message_body.to_xml @to_xml_options + when :json + return @message_body.to_json + when :yaml + return @message_body.to_yaml + else + @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 + + private + def query_string(hash) + build_query_string(hash, nil, nil) + end + + 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 + + def set_content_type(type) + http_header("Content-type", type) + end + end +end From kato-k at rubyforge.org Fri Aug 24 05:33:16 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 24 Aug 2007 05:33:16 -0400 (EDT) Subject: [ap4r-devel] [261] tags/200709_gihyo_async_shop/: tag 200709_gihyo_async_shop Message-ID: <20070824093317.2EC3F5240A4F@rubyforge.org> Revision: 261 Author: kato-k Date: 2007-08-24 05:33:15 -0400 (Fri, 24 Aug 2007) Log Message: ----------- tag 200709_gihyo_async_shop Added Paths: ----------- tags/200709_gihyo_async_shop/ Copied: tags/200709_gihyo_async_shop (from rev 260, branches/200709_gihyo/async_shop) From kato-k at rubyforge.org Mon Aug 27 01:52:18 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Mon, 27 Aug 2007 01:52:18 -0400 (EDT) Subject: [ap4r-devel] [262] tags/200709_gihyo_sync_shop/as_rails/app: Refactoring: method name etc. Message-ID: <20070827055218.1B1615240F87@rubyforge.org> Revision: 262 Author: kato-k Date: 2007-08-27 01:52:16 -0400 (Mon, 27 Aug 2007) Log Message: ----------- Refactoring: method name etc. Modified Paths: -------------- tags/200709_gihyo_sync_shop/as_rails/app/controllers/async_shop_controller.rb tags/200709_gihyo_sync_shop/as_rails/app/models/order.rb tags/200709_gihyo_sync_shop/as_rails/app/models/payment.rb Added Paths: ----------- tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/index.rhtml tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/order_form.rhtml Removed Paths: ------------- tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/list.rhtml tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/new.rhtml Modified: tags/200709_gihyo_sync_shop/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-24 09:33:15 UTC (rev 261) +++ tags/200709_gihyo_sync_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-27 05:52:16 UTC (rev 262) @@ -1,34 +1,35 @@ class AsyncShopController < ApplicationController def index - list - render :action => 'list' - end - - def list @order_pages, @orders = paginate :orders, :per_page => 10 end - def new + def order_form @order = Order.new end def order begin - ActiveRecord::Base.transaction do + Order.transaction do @order = Order.new(params[:order]) @order.save payment(@order[:id]) flash[:notice] = 'Order was successfully created.' - redirect_to :action => 'list' + redirect_to :action => 'index' end rescue Exception flash[:notice] = 'Order was failed.' - render :action => 'new' + render :action => 'order_form' end end + def destroy_order + Order.find(params[:id]).destroy + redirect_to :action => 'index' + end + + private def payment(order_id) sleep 5 @@ -37,9 +38,4 @@ payment.save end - def destroy - Order.find(params[:id]).destroy - redirect_to :action => 'list' - end - end Modified: tags/200709_gihyo_sync_shop/as_rails/app/models/order.rb =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/app/models/order.rb 2007-08-24 09:33:15 UTC (rev 261) +++ tags/200709_gihyo_sync_shop/as_rails/app/models/order.rb 2007-08-27 05:52:16 UTC (rev 262) @@ -1,2 +1,3 @@ class Order < ActiveRecord::Base + has_one :payment end Modified: tags/200709_gihyo_sync_shop/as_rails/app/models/payment.rb =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/app/models/payment.rb 2007-08-24 09:33:15 UTC (rev 261) +++ tags/200709_gihyo_sync_shop/as_rails/app/models/payment.rb 2007-08-27 05:52:16 UTC (rev 262) @@ -1,2 +1,3 @@ class Payment < ActiveRecord::Base + belongs_to :order end Copied: tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/index.rhtml (from rev 261, tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/list.rhtml) =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/index.rhtml (rev 0) +++ tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/index.rhtml 2007-08-27 05:52:16 UTC (rev 262) @@ -0,0 +1,25 @@ +

Listing orders

+ + + + + + + + +<% for order in @orders %> + + + + + + +<% end %> +
ItemOrdered atPayed at
<%=h order.item %><%=h order.created_at %><%=h begin order.payment.created_at rescue "not yet." end %><%= link_to 'Destroy', { :action => 'destroy_order', :id => order }, :confirm => 'Are you sure?', :method => :post %>
+ +<%= link_to 'Previous page', { :page => @order_pages.current.previous } if @order_pages.current.previous %> +<%= link_to 'Next page', { :page => @order_pages.current.next } if @order_pages.current.next %> + +
+ +<%= link_to 'New order', :action => 'order_form' %> Deleted: tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/list.rhtml =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-24 09:33:15 UTC (rev 261) +++ tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-27 05:52:16 UTC (rev 262) @@ -1,25 +0,0 @@ -

Listing orders

- - - - - - - -<% for order in @orders %> - - - - - - -<% end %> -
ItemOrdered atPayed at -
<%=h order.item %><%=h order.created_at %><%=h begin Payment.find_by_order_id(order.id).created_at rescue "not yet." end %><%= link_to 'Destroy', { :action => 'destroy', :id => order }, :confirm => 'Are you sure?', :method => :post %>
- -<%= link_to 'Previous page', { :page => @order_pages.current.previous } if @order_pages.current.previous %> -<%= link_to 'Next page', { :page => @order_pages.current.next } if @order_pages.current.next %> - -
- -<%= link_to 'New order', :action => 'new' %> Deleted: tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/new.rhtml =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/new.rhtml 2007-08-24 09:33:15 UTC (rev 261) +++ tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/new.rhtml 2007-08-27 05:52:16 UTC (rev 262) @@ -1,10 +0,0 @@ -

New order

- -<% form_tag :action => 'order' do %> - <%= error_messages_for 'order' %> -


- <%= text_field 'order', 'item' %>

- <%= submit_tag "Order" %> -<% end %> - -<%= link_to 'ordered list', :action => 'list' %> Copied: tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/order_form.rhtml (from rev 261, tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/new.rhtml) =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/order_form.rhtml (rev 0) +++ tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/order_form.rhtml 2007-08-27 05:52:16 UTC (rev 262) @@ -0,0 +1,10 @@ +

New order

+ +<% form_tag :action => 'order' do %> + <%= error_messages_for 'order' %> +


+ <%= text_field 'order', 'item' %>

+ <%= submit_tag "Order" %> +<% end %> + +<%= link_to 'ordered list', :action => 'index' %> From kato-k at rubyforge.org Mon Aug 27 04:11:53 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Mon, 27 Aug 2007 04:11:53 -0400 (EDT) Subject: [ap4r-devel] [263] tags: Refactoring: method name etc. Message-ID: <20070827081153.AC4ADA97000F@rubyforge.org> Revision: 263 Author: kato-k Date: 2007-08-27 04:11:50 -0400 (Mon, 27 Aug 2007) Log Message: ----------- Refactoring: method name etc. Modified Paths: -------------- tags/200709_gihyo_async_shop/as_rails/app/controllers/async_shop_controller.rb tags/200709_gihyo_async_shop/as_rails/app/models/order.rb tags/200709_gihyo_async_shop/as_rails/app/models/payment.rb tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/order_form.rhtml Added Paths: ----------- tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/index.rhtml tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/order_form.rhtml Removed Paths: ------------- tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/list.rhtml tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/new.rhtml Modified: tags/200709_gihyo_async_shop/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- tags/200709_gihyo_async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-27 05:52:16 UTC (rev 262) +++ tags/200709_gihyo_async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-27 08:11:50 UTC (rev 263) @@ -1,21 +1,16 @@ class AsyncShopController < ApplicationController def index - list - render :action => 'list' - end - - def list @order_pages, @orders = paginate :orders, :per_page => 10 end - def new + def order_form @order = Order.new end def order begin - ActiveRecord::Base.transaction do + Order.transaction do @order = Order.new(params[:order]) @order.save @@ -23,14 +18,19 @@ {:order_id => @order.id}) flash[:notice] = 'Order was successfully created.' - redirect_to :action => 'list' + redirect_to :action => 'index' end rescue Exception flash[:notice] = 'Order was failed.' - render :action => 'new' + render :action => 'order_form' end end + def destroy_order + Order.find(params[:id]).destroy + redirect_to :action => 'index' + end + def payment sleep 5 @@ -40,9 +40,4 @@ render :text => "true" end - def destroy - Order.find(params[:id]).destroy - redirect_to :action => 'list' - end - end Modified: tags/200709_gihyo_async_shop/as_rails/app/models/order.rb =================================================================== --- tags/200709_gihyo_async_shop/as_rails/app/models/order.rb 2007-08-27 05:52:16 UTC (rev 262) +++ tags/200709_gihyo_async_shop/as_rails/app/models/order.rb 2007-08-27 08:11:50 UTC (rev 263) @@ -1,2 +1,3 @@ class Order < ActiveRecord::Base + has_one :payment end Modified: tags/200709_gihyo_async_shop/as_rails/app/models/payment.rb =================================================================== --- tags/200709_gihyo_async_shop/as_rails/app/models/payment.rb 2007-08-27 05:52:16 UTC (rev 262) +++ tags/200709_gihyo_async_shop/as_rails/app/models/payment.rb 2007-08-27 08:11:50 UTC (rev 263) @@ -1,2 +1,3 @@ class Payment < ActiveRecord::Base + belongs_to :order end Copied: tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/index.rhtml (from rev 261, tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/list.rhtml) =================================================================== --- tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/index.rhtml (rev 0) +++ tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/index.rhtml 2007-08-27 08:11:50 UTC (rev 263) @@ -0,0 +1,25 @@ +

Listing orders

+ + + + + + + + +<% for order in @orders %> + + + + + + +<% end %> +
ItemOrdered atPayed at
<%=h order.item %><%=h order.created_at %><%=h begin order.payment.created_at rescue "not yet." end %><%= link_to 'Destroy', { :action => 'destroy_order', :id => order }, :confirm => 'Are you sure?', :method => :post %>
+ +<%= link_to 'Previous page', { :page => @order_pages.current.previous } if @order_pages.current.previous %> +<%= link_to 'Next page', { :page => @order_pages.current.next } if @order_pages.current.next %> + +
+ +<%= link_to 'New order', :action => 'order_form' %> Deleted: tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/list.rhtml =================================================================== --- tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-27 05:52:16 UTC (rev 262) +++ tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-27 08:11:50 UTC (rev 263) @@ -1,25 +0,0 @@ -

Listing orders

- - - - - - - -<% for order in @orders %> - - - - - - -<% end %> -
ItemOrdered atPayed at -
<%=h order.item %><%=h order.created_at %><%=h begin Payment.find_by_order_id(order.id).created_at rescue "not yet." end %><%= link_to 'Destroy', { :action => 'destroy', :id => order }, :confirm => 'Are you sure?', :method => :post %>
- -<%= link_to 'Previous page', { :page => @order_pages.current.previous } if @order_pages.current.previous %> -<%= link_to 'Next page', { :page => @order_pages.current.next } if @order_pages.current.next %> - -
- -<%= link_to 'New order', :action => 'new' %> Deleted: tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/new.rhtml =================================================================== --- tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/new.rhtml 2007-08-27 05:52:16 UTC (rev 262) +++ tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/new.rhtml 2007-08-27 08:11:50 UTC (rev 263) @@ -1,10 +0,0 @@ -

New order

- -<% form_tag :action => 'order' do %> - <%= error_messages_for 'order' %> -


- <%= text_field 'order', 'item' %>

- <%= submit_tag "Order" %> -<% end %> - -<%= link_to 'ordered list', :action => 'list' %> Copied: tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/order_form.rhtml (from rev 261, tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/new.rhtml) =================================================================== --- tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/order_form.rhtml (rev 0) +++ tags/200709_gihyo_async_shop/as_rails/app/views/async_shop/order_form.rhtml 2007-08-27 08:11:50 UTC (rev 263) @@ -0,0 +1,10 @@ +

New order

+ +<% form_tag :action => 'order' do %> + <%= error_messages_for 'order' %> +


+ <%= text_field 'order', 'item' %>

+ <%= submit_tag "Order" %> +<% end %> + +<%= link_to 'ordered list', :action => 'index' %> Modified: tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/order_form.rhtml =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/order_form.rhtml 2007-08-27 05:52:16 UTC (rev 262) +++ tags/200709_gihyo_sync_shop/as_rails/app/views/async_shop/order_form.rhtml 2007-08-27 08:11:50 UTC (rev 263) @@ -2,7 +2,7 @@ <% form_tag :action => 'order' do %> <%= error_messages_for 'order' %> -


+


<%= text_field 'order', 'item' %>

<%= submit_tag "Order" %> <% end %> From kato-k at rubyforge.org Mon Aug 27 04:34:50 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Mon, 27 Aug 2007 04:34:50 -0400 (EDT) Subject: [ap4r-devel] [264] branches/200709_gihyo/async_shop: Modified: async_shop application with url rewrite. Message-ID: <20070827083450.C1549524098A@rubyforge.org> Revision: 264 Author: kato-k Date: 2007-08-27 04:34:46 -0400 (Mon, 27 Aug 2007) Log Message: ----------- Modified: async_shop application with url rewrite. Modified Paths: -------------- branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb branches/200709_gihyo/async_shop/as_rails/app/models/order.rb branches/200709_gihyo/async_shop/as_rails/app/models/payment.rb Added Paths: ----------- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/index.rhtml branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/order_form.rhtml branches/200709_gihyo/async_shop/as_rails/config/mongrel_cluster.yml Removed Paths: ------------- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml Modified: branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg 2007-08-27 08:11:50 UTC (rev 263) +++ branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg 2007-08-27 08:34:46 UTC (rev 264) @@ -12,7 +12,9 @@ dispatchers: - targets: queue.* - threads: 1 + threads: 3 + modify_rules: + url: "Proc.new {|url| url.port = 4001 + rand(3)}" #carriers: # - # source_uri: druby://another.host.local:6438 Modified: branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-27 08:11:50 UTC (rev 263) +++ branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-27 08:34:46 UTC (rev 264) @@ -1,21 +1,16 @@ class AsyncShopController < ApplicationController def index - list - render :action => 'list' - end - - def list @order_pages, @orders = paginate :orders, :per_page => 10 end - def new + def order_form @order = Order.new end def order begin - ActiveRecord::Base.transaction do + Order.transaction do @order = Order.new(params[:order]) @order.save @@ -23,14 +18,19 @@ {:order_id => @order.id}) flash[:notice] = 'Order was successfully created.' - redirect_to :action => 'list' + redirect_to :action => 'index' end rescue Exception flash[:notice] = 'Order was failed.' - render :action => 'new' + render :action => 'order_form' end end + def destroy_order + Order.find(params[:id]).destroy + redirect_to :action => 'index' + end + def payment sleep 5 @@ -40,9 +40,4 @@ render :text => "true" end - def destroy - Order.find(params[:id]).destroy - redirect_to :action => 'list' - end - end Modified: branches/200709_gihyo/async_shop/as_rails/app/models/order.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/models/order.rb 2007-08-27 08:11:50 UTC (rev 263) +++ branches/200709_gihyo/async_shop/as_rails/app/models/order.rb 2007-08-27 08:34:46 UTC (rev 264) @@ -1,2 +1,3 @@ class Order < ActiveRecord::Base + has_one :payment end Modified: branches/200709_gihyo/async_shop/as_rails/app/models/payment.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/models/payment.rb 2007-08-27 08:11:50 UTC (rev 263) +++ branches/200709_gihyo/async_shop/as_rails/app/models/payment.rb 2007-08-27 08:34:46 UTC (rev 264) @@ -1,2 +1,3 @@ class Payment < ActiveRecord::Base + belongs_to :order end Copied: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/index.rhtml (from rev 261, branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml) =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/index.rhtml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/index.rhtml 2007-08-27 08:34:46 UTC (rev 264) @@ -0,0 +1,25 @@ +

Listing orders

+ + + + + + + + +<% for order in @orders %> + + + + + + +<% end %> +
ItemOrdered atPayed at
<%=h order.item %><%=h order.created_at %><%=h begin order.payment.created_at rescue "not yet." end %><%= link_to 'Destroy', { :action => 'destroy_order', :id => order }, :confirm => 'Are you sure?', :method => :post %>
+ +<%= link_to 'Previous page', { :page => @order_pages.current.previous } if @order_pages.current.previous %> +<%= link_to 'Next page', { :page => @order_pages.current.next } if @order_pages.current.next %> + +
+ +<%= link_to 'New order', :action => 'order_form' %> Deleted: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-27 08:11:50 UTC (rev 263) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/list.rhtml 2007-08-27 08:34:46 UTC (rev 264) @@ -1,25 +0,0 @@ -

Listing orders

- - - - - - - -<% for order in @orders %> - - - - - - -<% end %> -
ItemOrdered atPayed at -
<%=h order.item %><%=h order.created_at %><%=h begin Payment.find_by_order_id(order.id).created_at rescue "not yet." end %><%= link_to 'Destroy', { :action => 'destroy', :id => order }, :confirm => 'Are you sure?', :method => :post %>
- -<%= link_to 'Previous page', { :page => @order_pages.current.previous } if @order_pages.current.previous %> -<%= link_to 'Next page', { :page => @order_pages.current.next } if @order_pages.current.next %> - -
- -<%= link_to 'New order', :action => 'new' %> Deleted: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml 2007-08-27 08:11:50 UTC (rev 263) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml 2007-08-27 08:34:46 UTC (rev 264) @@ -1,10 +0,0 @@ -

New order

- -<% form_tag :action => 'order' do %> - <%= error_messages_for 'order' %> -


- <%= text_field 'order', 'item' %>

- <%= submit_tag "Order" %> -<% end %> - -<%= link_to 'ordered list', :action => 'list' %> Copied: branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/order_form.rhtml (from rev 261, branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/new.rhtml) =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/order_form.rhtml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/app/views/async_shop/order_form.rhtml 2007-08-27 08:34:46 UTC (rev 264) @@ -0,0 +1,10 @@ +

New order

+ +<% form_tag :action => 'order' do %> + <%= error_messages_for 'order' %> +


+ <%= text_field 'order', 'item' %>

+ <%= submit_tag "Order" %> +<% end %> + +<%= link_to 'ordered list', :action => 'index' %> Added: branches/200709_gihyo/async_shop/as_rails/config/mongrel_cluster.yml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/config/mongrel_cluster.yml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/config/mongrel_cluster.yml 2007-08-27 08:34:46 UTC (rev 264) @@ -0,0 +1,6 @@ +--- +log_file: log/mongrel.log +port: "4000" +environment: development +pid_file: tmp/pids/mongrel.pid +servers: 4 From kato-k at rubyforge.org Mon Aug 27 04:38:59 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Mon, 27 Aug 2007 04:38:59 -0400 (EDT) Subject: [ap4r-devel] [265] tags/200709_gihyo_async_shop_with_url_rewrite/: tag 200709_gihyo_async_shop_with_url_rewite Message-ID: <20070827083859.B93BF5240A8F@rubyforge.org> Revision: 265 Author: kato-k Date: 2007-08-27 04:38:59 -0400 (Mon, 27 Aug 2007) Log Message: ----------- tag 200709_gihyo_async_shop_with_url_rewite Added Paths: ----------- tags/200709_gihyo_async_shop_with_url_rewrite/ Copied: tags/200709_gihyo_async_shop_with_url_rewrite (from rev 264, branches/200709_gihyo/async_shop) From kato-k at rubyforge.org Mon Aug 27 04:39:25 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Mon, 27 Aug 2007 04:39:25 -0400 (EDT) Subject: [ap4r-devel] [266] tags/200709_gihyo_async_shop_with_url_rewrite/async_shop/: tag 200709_gihyo_async_shop_with_url_rewite Message-ID: <20070827083926.0103C524098A@rubyforge.org> Revision: 266 Author: kato-k Date: 2007-08-27 04:39:25 -0400 (Mon, 27 Aug 2007) Log Message: ----------- tag 200709_gihyo_async_shop_with_url_rewite Added Paths: ----------- tags/200709_gihyo_async_shop_with_url_rewrite/async_shop/ Copied: tags/200709_gihyo_async_shop_with_url_rewrite/async_shop (from rev 265, branches/200709_gihyo/async_shop) From shino at rubyforge.org Tue Aug 28 03:36:11 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 28 Aug 2007 03:36:11 -0400 (EDT) Subject: [ap4r-devel] [267] branches/200709_gihyo/async_shop/as_rails/test/fixtures: Change column names to current names in database. Message-ID: <20070828073612.0F619524096F@rubyforge.org> Revision: 267 Author: shino Date: 2007-08-28 03:36:11 -0400 (Tue, 28 Aug 2007) Log Message: ----------- Change column names to current names in database. Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml branches/200709_gihyo/async_shop/as_rails/test/fixtures/payments.yml Modified: branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml 2007-08-27 08:39:25 UTC (rev 266) +++ branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml 2007-08-28 07:36:11 UTC (rev 267) @@ -3,9 +3,9 @@ id: 1 customer_id: 1 item: MyString - orderd_at: 2007-08-23 + created_at: 2007-08-23 two: id: 2 customer_id: 1 item: MyString - orderd_at: 2007-08-23 + created_at: 2007-08-23 Modified: branches/200709_gihyo/async_shop/as_rails/test/fixtures/payments.yml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/fixtures/payments.yml 2007-08-27 08:39:25 UTC (rev 266) +++ branches/200709_gihyo/async_shop/as_rails/test/fixtures/payments.yml 2007-08-28 07:36:11 UTC (rev 267) @@ -2,8 +2,8 @@ one: id: 1 order_id: 1 - payed_at: 2007-08-23 + created_at: 2007-08-23 two: id: 2 order_id: 1 - payed_at: 2007-08-23 + created_at: 2007-08-23 From shino at rubyforge.org Tue Aug 28 03:40:28 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 28 Aug 2007 03:40:28 -0400 (EDT) Subject: [ap4r-devel] [268] branches/200709_gihyo/async_shop/as_rails/test: Add AP4R test stub not to use network. Message-ID: <20070828074028.4B77F5240F35@rubyforge.org> Revision: 268 Author: shino Date: 2007-08-28 03:40:27 -0400 (Tue, 28 Aug 2007) Log Message: ----------- Add AP4R test stub not to use network. This stub code should be moved to AP4R modules. (needs refactoring) Add a test case which assert a (would-be) queued message. Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/test/functional/async_shop_controller_test.rb branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb Modified: branches/200709_gihyo/async_shop/as_rails/test/functional/async_shop_controller_test.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/functional/async_shop_controller_test.rb 2007-08-28 07:36:11 UTC (rev 267) +++ branches/200709_gihyo/async_shop/as_rails/test/functional/async_shop_controller_test.rb 2007-08-28 07:40:27 UTC (rev 268) @@ -15,4 +15,17 @@ def test_truth assert true end + + def test_order + post :order, :order => {:item => "introduction to AP4R"} + assert_response :redirect + assert_redirected_to :action => 'index' + + messages = @controller.ap4r.queued_messages + assert_equal 1, messages.keys.size, "should have just ONE queued message" + assert messages.key?("queue.async_shop.payment"), "queue name is INCORRECT" + assert_match /order_id=\d+/, messages["queue.async_shop.payment"].first[:message], + "parameter order_id should be included" + end + end Modified: branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb 2007-08-28 07:36:11 UTC (rev 267) +++ branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb 2007-08-28 07:40:27 UTC (rev 268) @@ -26,3 +26,23 @@ # Add more helper methods to be used by all tests here... end + +module Ap4r + module AsyncHelper + module Base + def queued_messages + return @queued_messages if @queued_messages + @queued_messages = Hash.new {|hash, key| hash[key] = []} + return @queued_messages + end + + private + def __queue_put(queue_name, queue_message, queue_headers) + puts queued_messages + puts queued_messages[queue_name] + queued_messages[queue_name] << {:headers => queue_headers, :message => queue_message} + end + + end + end +end From shino at rubyforge.org Tue Aug 28 03:40:59 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 28 Aug 2007 03:40:59 -0400 (EDT) Subject: [ap4r-devel] [269] branches/200709_gihyo/async_shop/as_rails/log/test.log: remove a log file Message-ID: <20070828074059.593725240FA7@rubyforge.org> Revision: 269 Author: shino Date: 2007-08-28 03:40:58 -0400 (Tue, 28 Aug 2007) Log Message: ----------- remove a log file Removed Paths: ------------- branches/200709_gihyo/async_shop/as_rails/log/test.log Deleted: branches/200709_gihyo/async_shop/as_rails/log/test.log =================================================================== From shino at rubyforge.org Tue Aug 28 03:44:12 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 28 Aug 2007 03:44:12 -0400 (EDT) Subject: [ap4r-devel] [270] branches/200709_gihyo/async_shop/as_rails/: add svn:ignore Message-ID: <20070828074412.DAFA05240FA7@rubyforge.org> Revision: 270 Author: shino Date: 2007-08-28 03:44:11 -0400 (Tue, 28 Aug 2007) Log Message: ----------- add svn:ignore Property Changed: ---------------- branches/200709_gihyo/async_shop/as_rails/ Property changes on: branches/200709_gihyo/async_shop/as_rails ___________________________________________________________________ Name: svn:ignore + tmp log From shino at rubyforge.org Tue Aug 28 04:26:04 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 28 Aug 2007 04:26:04 -0400 (EDT) Subject: [ap4r-devel] [271] branches/200709_gihyo/async_shop/as_rails/db/: add svn:ignore Message-ID: <20070828082605.C3F945240F9F@rubyforge.org> Revision: 271 Author: shino Date: 2007-08-28 04:25:55 -0400 (Tue, 28 Aug 2007) Log Message: ----------- add svn:ignore Property Changed: ---------------- branches/200709_gihyo/async_shop/as_rails/db/ Property changes on: branches/200709_gihyo/async_shop/as_rails/db ___________________________________________________________________ Name: svn:ignore + schema.rb From shino at rubyforge.org Tue Aug 28 21:32:28 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 28 Aug 2007 21:32:28 -0400 (EDT) Subject: [ap4r-devel] [272] branches/200709_gihyo/async_shop/as_rails: Refactor: move test helper code to AP4R's plugin. Message-ID: <20070829013228.2227D5240B99@rubyforge.org> Revision: 272 Author: shino Date: 2007-08-28 21:32:26 -0400 (Tue, 28 Aug 2007) Log Message: ----------- Refactor: move test helper code to AP4R's plugin. Add: some svn:ignore's Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb Added Paths: ----------- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_test_help.rb Property Changed: ---------------- branches/200709_gihyo/async_shop/as_rails/ branches/200709_gihyo/async_shop/as_rails/log/ branches/200709_gihyo/async_shop/as_rails/tmp/cache/ branches/200709_gihyo/async_shop/as_rails/tmp/pids/ branches/200709_gihyo/async_shop/as_rails/tmp/sessions/ branches/200709_gihyo/async_shop/as_rails/tmp/sockets/ Property changes on: branches/200709_gihyo/async_shop/as_rails ___________________________________________________________________ Name: svn:ignore - tmp log + Property changes on: branches/200709_gihyo/async_shop/as_rails/log ___________________________________________________________________ Name: svn:ignore + * Modified: branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb 2007-08-28 08:25:55 UTC (rev 271) +++ branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb 2007-08-29 01:32:26 UTC (rev 272) @@ -1,6 +1,7 @@ ENV["RAILS_ENV"] = "test" require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require 'test_help' +require 'ap4r_test_help' class Test::Unit::TestCase # Transactional fixtures accelerate your tests by wrapping each test method @@ -27,22 +28,3 @@ # Add more helper methods to be used by all tests here... end -module Ap4r - module AsyncHelper - module Base - def queued_messages - return @queued_messages if @queued_messages - @queued_messages = Hash.new {|hash, key| hash[key] = []} - return @queued_messages - end - - private - def __queue_put(queue_name, queue_message, queue_headers) - puts queued_messages - puts queued_messages[queue_name] - queued_messages[queue_name] << {:headers => queue_headers, :message => queue_message} - end - - end - end -end Property changes on: branches/200709_gihyo/async_shop/as_rails/tmp/cache ___________________________________________________________________ Name: svn:ignore + * Property changes on: branches/200709_gihyo/async_shop/as_rails/tmp/pids ___________________________________________________________________ Name: svn:ignore + * Property changes on: branches/200709_gihyo/async_shop/as_rails/tmp/sessions ___________________________________________________________________ Name: svn:ignore + * Property changes on: branches/200709_gihyo/async_shop/as_rails/tmp/sockets ___________________________________________________________________ Name: svn:ignore + * Added: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_test_help.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_test_help.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_test_help.rb 2007-08-29 01:32:26 UTC (rev 272) @@ -0,0 +1,21 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +module Ap4r + module AsyncHelper + module Base + def queued_messages + return @queued_messages if @queued_messages + @queued_messages = Hash.new {|hash, key| hash[key] = []} + return @queued_messages + end + + private + def __queue_put(queue_name, message, headers) + queued_messages[queue_name] << {:headers => headers, :message => message} + end + + end + end +end From shino at rubyforge.org Tue Aug 28 21:45:41 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 28 Aug 2007 21:45:41 -0400 (EDT) Subject: [ap4r-devel] [273] branches/200709_gihyo/async_shop/as_rails: rename file (it's just a stub) Message-ID: <20070829014541.4E8435240E78@rubyforge.org> Revision: 273 Author: shino Date: 2007-08-28 21:45:41 -0400 (Tue, 28 Aug 2007) Log Message: ----------- rename file (it's just a stub) Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb Added Paths: ----------- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/queue_put_stub.rb Removed Paths: ------------- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_test_help.rb Modified: branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb 2007-08-29 01:32:26 UTC (rev 272) +++ branches/200709_gihyo/async_shop/as_rails/test/test_helper.rb 2007-08-29 01:45:41 UTC (rev 273) @@ -1,7 +1,7 @@ ENV["RAILS_ENV"] = "test" require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require 'test_help' -require 'ap4r_test_help' +require 'ap4r/queue_put_stub' class Test::Unit::TestCase # Transactional fixtures accelerate your tests by wrapping each test method Copied: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/queue_put_stub.rb (from rev 272, branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_test_help.rb) =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/queue_put_stub.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/queue_put_stub.rb 2007-08-29 01:45:41 UTC (rev 273) @@ -0,0 +1,21 @@ +# Author:: Shunichi Shinohara +# Copyright:: Copyright (c) 2007 Future Architect Inc. +# Licence:: MIT Licence + +module Ap4r + module AsyncHelper + module Base + def queued_messages + return @queued_messages if @queued_messages + @queued_messages = Hash.new {|hash, key| hash[key] = []} + return @queued_messages + end + + private + def __queue_put(queue_name, message, headers) + queued_messages[queue_name] << {:headers => headers, :message => message} + end + + end + end +end Deleted: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_test_help.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_test_help.rb 2007-08-29 01:32:26 UTC (rev 272) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r_test_help.rb 2007-08-29 01:45:41 UTC (rev 273) @@ -1,21 +0,0 @@ -# Author:: Shunichi Shinohara -# Copyright:: Copyright (c) 2007 Future Architect Inc. -# Licence:: MIT Licence - -module Ap4r - module AsyncHelper - module Base - def queued_messages - return @queued_messages if @queued_messages - @queued_messages = Hash.new {|hash, key| hash[key] = []} - return @queued_messages - end - - private - def __queue_put(queue_name, message, headers) - queued_messages[queue_name] << {:headers => headers, :message => message} - end - - end - end -end From kato-k at rubyforge.org Tue Aug 28 21:50:14 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Tue, 28 Aug 2007 21:50:14 -0400 (EDT) Subject: [ap4r-devel] [274] branches/200709_gihyo/async_shop: Fixed: small bugs and etc. Message-ID: <20070829015014.37EBB5240F46@rubyforge.org> Revision: 274 Author: kato-k Date: 2007-08-28 21:50:13 -0400 (Tue, 28 Aug 2007) Log Message: ----------- Fixed: small bugs and etc. Modified Paths: -------------- branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb branches/200709_gihyo/async_shop/as_rails/db/migrate/001_create_orders.rb branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml Modified: branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg 2007-08-29 01:45:41 UTC (rev 273) +++ branches/200709_gihyo/async_shop/as_ap4r/config/queues_mysql.cfg 2007-08-29 01:50:13 UTC (rev 274) @@ -8,14 +8,10 @@ drb: host: port: 6438 - acl: allow 127.0.0.1 allow 10.0.0.0/8 allow ::1 + acl: allow 127.0.0.1 allow ::1 dispatchers: - targets: queue.* threads: 3 modify_rules: - url: "Proc.new {|url| url.port = 4001 + rand(3)}" -#carriers: -# - -# source_uri: druby://another.host.local:6438 -# threads: 1 + url: "proc {|url| url.port = 4001 + rand(3)}" Modified: branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-29 01:45:41 UTC (rev 273) +++ branches/200709_gihyo/async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-29 01:50:13 UTC (rev 274) @@ -12,7 +12,7 @@ begin Order.transaction do @order = Order.new(params[:order]) - @order.save + @order.save! ap4r.async_to({:action => 'payment'}, {:order_id => @order.id}) @@ -36,7 +36,7 @@ payment = Payment.new payment.order_id = params[:order_id] - payment.save + payment.save! render :text => "true" end Modified: branches/200709_gihyo/async_shop/as_rails/db/migrate/001_create_orders.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/db/migrate/001_create_orders.rb 2007-08-29 01:45:41 UTC (rev 273) +++ branches/200709_gihyo/async_shop/as_rails/db/migrate/001_create_orders.rb 2007-08-29 01:50:13 UTC (rev 274) @@ -1,7 +1,6 @@ class CreateOrders < ActiveRecord::Migration def self.up create_table :orders do |t| - t.column :customer_id, :integer t.column :item, :string t.column :created_at, :datetime end Modified: branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml 2007-08-29 01:45:41 UTC (rev 273) +++ branches/200709_gihyo/async_shop/as_rails/test/fixtures/orders.yml 2007-08-29 01:50:13 UTC (rev 274) @@ -1,11 +1,9 @@ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html one: id: 1 - customer_id: 1 item: MyString created_at: 2007-08-23 two: id: 2 - customer_id: 1 item: MyString created_at: 2007-08-23 From kato-k at rubyforge.org Tue Aug 28 21:51:00 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Tue, 28 Aug 2007 21:51:00 -0400 (EDT) Subject: [ap4r-devel] [275] tags: Fixed: small bugs and etc. Message-ID: <20070829015100.2F8015240F9C@rubyforge.org> Revision: 275 Author: kato-k Date: 2007-08-28 21:50:59 -0400 (Tue, 28 Aug 2007) Log Message: ----------- Fixed: small bugs and etc. Modified Paths: -------------- tags/200709_gihyo_async_shop/as_ap4r/config/queues_mysql.cfg tags/200709_gihyo_async_shop/as_rails/app/controllers/async_shop_controller.rb tags/200709_gihyo_async_shop/as_rails/db/migrate/001_create_orders.rb tags/200709_gihyo_async_shop/as_rails/test/fixtures/orders.yml tags/200709_gihyo_async_shop_with_url_rewrite/as_ap4r/config/queues_mysql.cfg tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/app/controllers/async_shop_controller.rb tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/db/migrate/001_create_orders.rb tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/test/fixtures/orders.yml tags/200709_gihyo_sync_shop/as_rails/app/controllers/async_shop_controller.rb tags/200709_gihyo_sync_shop/as_rails/db/migrate/001_create_orders.rb tags/200709_gihyo_sync_shop/as_rails/test/fixtures/orders.yml Modified: tags/200709_gihyo_async_shop/as_ap4r/config/queues_mysql.cfg =================================================================== --- tags/200709_gihyo_async_shop/as_ap4r/config/queues_mysql.cfg 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_async_shop/as_ap4r/config/queues_mysql.cfg 2007-08-29 01:50:59 UTC (rev 275) @@ -8,12 +8,8 @@ drb: host: port: 6438 - acl: allow 127.0.0.1 allow 10.0.0.0/8 allow ::1 + acl: allow 127.0.0.1 allow ::1 dispatchers: - targets: queue.* threads: 1 -#carriers: -# - -# source_uri: druby://another.host.local:6438 -# threads: 1 Modified: tags/200709_gihyo_async_shop/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- tags/200709_gihyo_async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_async_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-29 01:50:59 UTC (rev 275) @@ -12,7 +12,7 @@ begin Order.transaction do @order = Order.new(params[:order]) - @order.save + @order.save! ap4r.async_to({:action => 'payment'}, {:order_id => @order.id}) @@ -36,7 +36,7 @@ payment = Payment.new payment.order_id = params[:order_id] - payment.save + payment.save! render :text => "true" end Modified: tags/200709_gihyo_async_shop/as_rails/db/migrate/001_create_orders.rb =================================================================== --- tags/200709_gihyo_async_shop/as_rails/db/migrate/001_create_orders.rb 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_async_shop/as_rails/db/migrate/001_create_orders.rb 2007-08-29 01:50:59 UTC (rev 275) @@ -1,7 +1,6 @@ class CreateOrders < ActiveRecord::Migration def self.up create_table :orders do |t| - t.column :customer_id, :integer t.column :item, :string t.column :created_at, :datetime end Modified: tags/200709_gihyo_async_shop/as_rails/test/fixtures/orders.yml =================================================================== --- tags/200709_gihyo_async_shop/as_rails/test/fixtures/orders.yml 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_async_shop/as_rails/test/fixtures/orders.yml 2007-08-29 01:50:59 UTC (rev 275) @@ -1,11 +1,9 @@ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html one: id: 1 - customer_id: 1 item: MyString orderd_at: 2007-08-23 two: id: 2 - customer_id: 1 item: MyString orderd_at: 2007-08-23 Modified: tags/200709_gihyo_async_shop_with_url_rewrite/as_ap4r/config/queues_mysql.cfg =================================================================== --- tags/200709_gihyo_async_shop_with_url_rewrite/as_ap4r/config/queues_mysql.cfg 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_async_shop_with_url_rewrite/as_ap4r/config/queues_mysql.cfg 2007-08-29 01:50:59 UTC (rev 275) @@ -8,14 +8,11 @@ drb: host: port: 6438 - acl: allow 127.0.0.1 allow 10.0.0.0/8 allow ::1 + acl: allow 127.0.0.1 allow ::1 dispatchers: - targets: queue.* threads: 3 modify_rules: - url: "Proc.new {|url| url.port = 4001 + rand(3)}" -#carriers: -# - -# source_uri: druby://another.host.local:6438 -# threads: 1 + url: "proc {|url| url.port = 4001 + rand(3)}" + Modified: tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/app/controllers/async_shop_controller.rb 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/app/controllers/async_shop_controller.rb 2007-08-29 01:50:59 UTC (rev 275) @@ -12,7 +12,7 @@ begin Order.transaction do @order = Order.new(params[:order]) - @order.save + @order.save! ap4r.async_to({:action => 'payment'}, {:order_id => @order.id}) @@ -36,7 +36,7 @@ payment = Payment.new payment.order_id = params[:order_id] - payment.save + payment.save! render :text => "true" end Modified: tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/db/migrate/001_create_orders.rb =================================================================== --- tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/db/migrate/001_create_orders.rb 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/db/migrate/001_create_orders.rb 2007-08-29 01:50:59 UTC (rev 275) @@ -1,7 +1,6 @@ class CreateOrders < ActiveRecord::Migration def self.up create_table :orders do |t| - t.column :customer_id, :integer t.column :item, :string t.column :created_at, :datetime end Modified: tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/test/fixtures/orders.yml =================================================================== --- tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/test/fixtures/orders.yml 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_async_shop_with_url_rewrite/as_rails/test/fixtures/orders.yml 2007-08-29 01:50:59 UTC (rev 275) @@ -1,11 +1,9 @@ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html one: id: 1 - customer_id: 1 item: MyString orderd_at: 2007-08-23 two: id: 2 - customer_id: 1 item: MyString orderd_at: 2007-08-23 Modified: tags/200709_gihyo_sync_shop/as_rails/app/controllers/async_shop_controller.rb =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_sync_shop/as_rails/app/controllers/async_shop_controller.rb 2007-08-29 01:50:59 UTC (rev 275) @@ -12,7 +12,7 @@ begin Order.transaction do @order = Order.new(params[:order]) - @order.save + @order.save! payment(@order[:id]) flash[:notice] = 'Order was successfully created.' @@ -35,7 +35,7 @@ payment = Payment.new payment.order_id = order_id - payment.save + payment.save! end end Modified: tags/200709_gihyo_sync_shop/as_rails/db/migrate/001_create_orders.rb =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/db/migrate/001_create_orders.rb 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_sync_shop/as_rails/db/migrate/001_create_orders.rb 2007-08-29 01:50:59 UTC (rev 275) @@ -1,7 +1,6 @@ class CreateOrders < ActiveRecord::Migration def self.up create_table :orders do |t| - t.column :customer_id, :integer t.column :item, :string t.column :created_at, :datetime end Modified: tags/200709_gihyo_sync_shop/as_rails/test/fixtures/orders.yml =================================================================== --- tags/200709_gihyo_sync_shop/as_rails/test/fixtures/orders.yml 2007-08-29 01:50:13 UTC (rev 274) +++ tags/200709_gihyo_sync_shop/as_rails/test/fixtures/orders.yml 2007-08-29 01:50:59 UTC (rev 275) @@ -1,11 +1,9 @@ # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html one: id: 1 - customer_id: 1 item: MyString orderd_at: 2007-08-23 two: id: 2 - customer_id: 1 item: MyString orderd_at: 2007-08-23 From shino at rubyforge.org Tue Aug 28 23:07:25 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Tue, 28 Aug 2007 23:07:25 -0400 (EDT) Subject: [ap4r-devel] [276] branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r: add ap4r rake file. Message-ID: <20070829030725.8E28E5240FA1@rubyforge.org> Revision: 276 Author: shino Date: 2007-08-28 23:07:25 -0400 (Tue, 28 Aug 2007) Log Message: ----------- add ap4r rake file. Now it has only one task "test:async" Added Paths: ----------- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake Added: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake 2007-08-29 03:07:25 UTC (rev 276) @@ -0,0 +1,8 @@ +namespace :test do + Rake::TestTask.new(:async => "db:test:prepare") do |t| + t.libs << "test" + t.pattern = 'test/async/**/*_test.rb' + t.verbose = true + end + Rake::Task['test:async'].comment = "Run the unit tests in test/async" +end From shino at rubyforge.org Wed Aug 29 21:58:42 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Wed, 29 Aug 2007 21:58:42 -0400 (EDT) Subject: [ap4r-devel] [277] trunk/ap4r/lib/ap4r/mongrel_ap4r.rb: Fix: fixed a bug that "mongrel_ap4r" in help message were displayed as "mongrel_rails" Message-ID: <20070830015842.0B14C5240BC6@rubyforge.org> Revision: 277 Author: shino Date: 2007-08-29 21:58:41 -0400 (Wed, 29 Aug 2007) Log Message: ----------- Fix: fixed a bug that "mongrel_ap4r" in help message were displayed as "mongrel_rails" Modified Paths: -------------- trunk/ap4r/lib/ap4r/mongrel_ap4r.rb Modified: trunk/ap4r/lib/ap4r/mongrel_ap4r.rb =================================================================== --- trunk/ap4r/lib/ap4r/mongrel_ap4r.rb 2007-08-29 03:07:25 UTC (rev 276) +++ trunk/ap4r/lib/ap4r/mongrel_ap4r.rb 2007-08-30 01:58:41 UTC (rev 277) @@ -6,6 +6,8 @@ require 'mongrel' require 'ap4r/mongrel' +Mongrel::Command::BANNER.gsub!("rails", "ap4r") + module Ap4r::Mongrel module Command @@ -17,6 +19,8 @@ klass.class_eval do |k| include(::Mongrel::Command::Base) end + + # TODO: Can subclass the return of RubyGems::GemPlugin ? 2007/04/16 by shino end From shino at rubyforge.org Wed Aug 29 22:01:27 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Wed, 29 Aug 2007 22:01:27 -0400 (EDT) Subject: [ap4r-devel] [278] trunk/ap4r/: set svn:ignore list (doc*, coverage*) Message-ID: <20070830020127.B0EE85240BCE@rubyforge.org> Revision: 278 Author: shino Date: 2007-08-29 22:01:26 -0400 (Wed, 29 Aug 2007) Log Message: ----------- set svn:ignore list (doc*, coverage*) Property Changed: ---------------- trunk/ap4r/ Property changes on: trunk/ap4r ___________________________________________________________________ Name: svn:ignore + doc* coverage* From shino at rubyforge.org Wed Aug 29 23:59:02 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Wed, 29 Aug 2007 23:59:02 -0400 (EDT) Subject: [ap4r-devel] [279] branches/200709_gihyo/async_shop: Add test support including asynchronous processing. Message-ID: <20070830035902.84C985240CF4@rubyforge.org> Revision: 279 Author: shino Date: 2007-08-29 23:59:01 -0400 (Wed, 29 Aug 2007) Log Message: ----------- Add test support including asynchronous processing. Now Rails and AP4R servers should be started manually. Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake Added Paths: ----------- branches/200709_gihyo/async_shop/as_ap4r/config/queues_test.cfg branches/200709_gihyo/async_shop/as_rails/config/test_async.yml branches/200709_gihyo/async_shop/as_rails/test/async/ branches/200709_gihyo/async_shop/as_rails/test/async/ap4r_test_helper.rb branches/200709_gihyo/async_shop/as_rails/test/async/async_shop_test.rb branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb Property Changed: ---------------- branches/200709_gihyo/async_shop/as_ap4r/log/ Added: branches/200709_gihyo/async_shop/as_ap4r/config/queues_test.cfg =================================================================== --- branches/200709_gihyo/async_shop/as_ap4r/config/queues_test.cfg (rev 0) +++ branches/200709_gihyo/async_shop/as_ap4r/config/queues_test.cfg 2007-08-30 03:59:01 UTC (rev 279) @@ -0,0 +1,19 @@ +--- +store: + type: mysql + host: localhost + database: ap4r + username: ap4r + password: ap4r +drb: + host: + port: 6438 + acl: allow 127.0.0.1 allow ::1 +dispatchers: + - + targets: queue.* + threads: 1 +#carriers: +# - +# source_uri: druby://another.host.local:6438 +# threads: 1 Property changes on: branches/200709_gihyo/async_shop/as_ap4r/log ___________________________________________________________________ Name: svn:ignore + * Added: branches/200709_gihyo/async_shop/as_rails/config/test_async.yml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/config/test_async.yml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/config/test_async.yml 2007-08-30 03:59:01 UTC (rev 279) @@ -0,0 +1,7 @@ +--- +ap4r: + root_dir: ../as_ap4r + config_file: config/queues_test.cfg + start_ruby_args: -I ~/d/ap4r-core-trunk/lib + stop_ruby_args: -I ~/d/ap4r-core-trunk/lib +rails: Added: branches/200709_gihyo/async_shop/as_rails/test/async/ap4r_test_helper.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/async/ap4r_test_helper.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/test/async/ap4r_test_helper.rb 2007-08-30 03:59:01 UTC (rev 279) @@ -0,0 +1,38 @@ +# 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 "ap4r/service_handler.rb" + +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 } + +# puts +# at_exit { puts } + +# Test::Unit also use at_exit hook, so load at the end +require 'test_help' + +class Test::Unit::TestCase + self.use_transactional_fixtures = false + self.use_instantiated_fixtures = false + + # Add more helper methods to be used by all tests here... + 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 Added: branches/200709_gihyo/async_shop/as_rails/test/async/async_shop_test.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/async/async_shop_test.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/test/async/async_shop_test.rb 2007-08-30 03:59:01 UTC (rev 279) @@ -0,0 +1,49 @@ +require "#{File.dirname(__FILE__)}/ap4r_test_helper" + +require 'net/http' + +# Test cases with ap4r integration. +# some comments: +# - Clearance of data in a database and queues should be included. +# - Workspaces of ap4r and rails should have some conventions for convinience. +# - Think about transition to RSpec. +# - HTTP session holding support is needed? +class AsyncShopTest < Test::Unit::TestCase + + def test_http_dispatch + ap4r_helper.stop_dispatchers + + assert_rows_added(Order, 1) { + do_order + } + + assert_rows_added(Payment, 1) { + ap4r_helper.start_dispatchers + ap4r_helper.wait_all_done + } + + end + + def test_just_fail + assert false + end + + private + + # Requests to async_shop/order. + def do_order(item_name = "test item") + Net::HTTP.start("localhost", 3000, nil, nil) do |http| + http.request_post("/async_shop/order", + "order[item]=#{item_name}") do |res| + #nop + end + end + end + + def assert_rows_added(model, rows) + rows_before = model.count + yield + rows_after = model.count + assert_equal rows, rows_after - rows_before, "table '#{model.table_name}' should count up by #{rows}" + end +end Added: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb 2007-08-30 03:59:01 UTC (rev 279) @@ -0,0 +1,161 @@ +# 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/test_async.yml") + raise "please create config/async_test.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["ap4r"] + @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 " + + "start -d -c #{@root_dir} -A #{@config_file} -p 13038" + 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 " + + "stop -c #{@root_dir}" + 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 + + require 'timeout' + # Stops rails service. + def stop_rails_service +# puts "read pid" +# pid = File.read('log/mongrel.pid').to_i +# puts "send signal to #{pid}" +# Process.kill(:TERM, `cat log/mongrel.pid`.to_i) +# puts "done" +# return + command = "mongrel_rails stop" +# command = "kill " + `cat log/mongrel.pid` + command = "sh -c 'mongrel_rails stop'" + message = "Terminating Mongrel(Rails)" + begin + timeout(5) do + execute_command(command, message, false) + end + rescue TimeoutError + puts "!!! command timed out !!!" + 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 start_dispatchers + qm.dispatchers.start + end + + def stop_dispatchers + qm.dispatchers.stop + 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 + + 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 + + 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 + + private + def execute_command(command, message, with_done_message = true) +# print "#{message} with command: #{command}..." + result = system(command, "") + # TODO: handle result 2007/08/29 by shino + puts "Done." if with_done_message + end + + def wait_until_alive(message = nil) + 50.times do + print message if message + begin + break if qm.alive? + rescue => e + # ignore + end + sleep 0.2 + end + end + +end Modified: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake 2007-08-30 02:01:26 UTC (rev 278) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake 2007-08-30 03:59:01 UTC (rev 279) @@ -1,8 +1,23 @@ namespace :test do - Rake::TestTask.new(:async => "db:test:prepare") do |t| - t.libs << "test" - t.pattern = 'test/async/**/*_test.rb' - t.verbose = true + +# task :asyncs do +# setup - run - teardown comes here. +# Names should be considered further. +# end + + namespace :asyncs do + desc "Start Rails and AP4R servers to test:asyncs:exec" + task :setup do |t| + puts "setup task should be implemented here" + end + + Rake::TestTask.new(:run => "db:test:prepare") do |t| + t.libs << "test" + t.pattern = 'test/async/**/*_test.rb' + t.verbose = true + end + Rake::Task['test:asyncs:run'].comment = "Run the unit tests in test/async" + end - Rake::Task['test:async'].comment = "Run the unit tests in test/async" + end From kato-k at rubyforge.org Thu Aug 30 01:49:18 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Thu, 30 Aug 2007 01:49:18 -0400 (EDT) Subject: [ap4r-devel] [280] trunk/ap4r/lib/ap4r: Fixed: fixed a bug that remaining messages in PostgreSQL are not loaded when AP4R restarts. Message-ID: <20070830054918.67FC75240CB3@rubyforge.org> Revision: 280 Author: kato-k Date: 2007-08-30 01:49:17 -0400 (Thu, 30 Aug 2007) Log Message: ----------- Fixed: fixed a bug that remaining messages in PostgreSQL are not loaded when AP4R restarts. Modified Paths: -------------- trunk/ap4r/lib/ap4r/message_store_ext.rb trunk/ap4r/lib/ap4r/postgresql.sql Modified: trunk/ap4r/lib/ap4r/message_store_ext.rb =================================================================== --- trunk/ap4r/lib/ap4r/message_store_ext.rb 2007-08-30 03:59:01 UTC (rev 279) +++ trunk/ap4r/lib/ap4r/message_store_ext.rb 2007-08-30 05:49:17 UTC (rev 280) @@ -38,7 +38,7 @@ # Make sure we have a PostgreSQL library before creating this class, # worst case we end up with a disk-based message store. Try the # native PostgreSQL library, followed by the pure Ruby PostgreSQL library. - begin + begin require 'postgres' rescue LoadError require 'postgres-pr/connection' @@ -123,10 +123,9 @@ begin inserts.each do |insert| if insert[:queue] - pgsql.query "INSERT INTO #{@queues_table} (id,queue,headers,object) VALUES('#{connection.quote insert[:id]}','#{connection.quote insert[:queue]}','#{connection.quote Marshal::dump(insert[:headers])}','#{connection.quote insert[:message]}')" -# pgsql.query "INSERT INTO #{@queues_table} (id,queue,headers,object) VALUES('#{connection.quote insert[:id]}','#{connection.quote insert[:queue]}',BINARY '#{connection.quote Marshal::dump(insert[:headers])}',BINARY '#{connection.quote insert[:message]}')" + pgsql.query "INSERT INTO #{@queues_table} (id,queue,headers,object) VALUES('#{connection.quote insert[:id]}', '#{connection.quote insert[:queue]}', '#{connection.quote YAML.dump(insert[:headers])}', '#{connection.quote insert[:message]}')" else - pgsql.query "REPLACE #{@topics_table} (topic,headers,object) VALUES('#{connection.quote insert[:topic]}','#{connection.quote Marshal::dump(insert[:headers])}','#{connection.quote insert[:message]}')" + pgsql.query "REPLACE #{@topics_table} (topic,headers,object) VALUES('#{connection.quote insert[:topic]}','#{connection.quote YAML.dump(insert[:headers])}','#{connection.quote insert[:message]}')" end end ids = deletes.inject([]) do |array, delete| @@ -149,9 +148,9 @@ def load_index connection.query "SELECT id,queue,headers FROM #{@queues_table}" do |result| - while row = result.fetch_row - queue = @queues[row[1]] ||= [] - headers = Marshal::load row[2] + result.each do |tuple| + queue = @queues[tuple[1]] ||= [] + headers = YAML.load tuple[2] # Add element based on priority, higher priority comes first. priority = headers[:priority] added = false @@ -166,8 +165,8 @@ end end connection.query "SELECT topic,headers FROM #{@topics_table}" do |result| - while row = result.fetch_row - @topics[row[0]] = Marshal::load row[1] + result.each do |tuple| + @topics[tuple[0]] = YAML.load tuple[1] end end end @@ -177,15 +176,11 @@ message = nil if type == :queue connection.query "SELECT object FROM #{@queues_table} WHERE id='#{id}'" do |result| - message = if row = result.fetch_row - row[0] - end + message = result[0][0] if result[0] end else connection.query "SELECT object FROM #{@topics_table} WHERE topic='#{queue_or_topic}'" do |result| - message = if row = result.fetch_row - row[0] - end + message = result[0][0] if result[0] end end message @@ -211,26 +206,61 @@ end end -class PGconn - def quote str - PGconn.escape str +if Object.const_defined? :PGError + class PGconn + alias original_query query + + def query(q, *bind_values, &block) + # In PGconn, +query+ method does NOT care about a given block. + # To deal with a given block, this method adds iteration + # over query results. + maybe_result = exec(q, *bind_values) + puts "PGconn: query called by #{q}" if $DEBUG + puts "PGconn#query returns #{maybe_result}(class: #{maybe_result.class})." if $DEBUG + return maybe_result unless block && maybe_result.kind_of?(PGresult) + begin + puts "PGconn extention: about to yield result." if $DEBUG + block.call(maybe_result) + ensure + maybe_result.clear + end + end + + def quote str + # do nothing + str + end + end end -module PostgresPR - class Connection - def escape_string(str) - str.gsub(/([\0\n\r\032\'\"\\])/) do - case $1 - when "\0" then "\\0" - when "\n" then "\\n" - when "\r" then "\\r" - when "\032" then "\\Z" - else "\\"+$1 +if Object.const_defined? :PostgresPR + module PostgresPR + class Connection + alias original_query query + + def query(q, &block) + # In PostgresPR, +query+ method does NOT care about a given block. + # To deal with a given block, this method adds iteration + # over query results. + maybe_result = original_query(q, &block) + puts "PostgresPR: query called by #{q}" if $DEBUG + puts "PostgresPR::Connenction#query returns #{maybe_result}(class: #{maybe_result.class})." if $DEBUG + return maybe_result.rows unless block && maybe_result.kind_of?(PostgresPR::Connection::Result) + begin + puts "PostgresPR extention: about to yield result." if $DEBUG + block.call(maybe_result.rows) + ensure + maybe_result = nil end end - end - alias :quote :escape_string + + def quote(str) + # do nothing + str + end + + end end end Modified: trunk/ap4r/lib/ap4r/postgresql.sql =================================================================== --- trunk/ap4r/lib/ap4r/postgresql.sql 2007-08-30 03:59:01 UTC (rev 279) +++ trunk/ap4r/lib/ap4r/postgresql.sql 2007-08-30 05:49:17 UTC (rev 280) @@ -2,12 +2,12 @@ id character varying(255) NOT NULL default '', queue character varying(255) NOT NULL default '', headers text NOT NULL, - object bytea NOT NULL, + object text NOT NULL, PRIMARY KEY (id) -) +); CREATE TABLE reliable_msg_topics ( topic character varying(255) NOT NULL default '', headers text NOT NULL, - object bytea NOT NULL, + object text NOT NULL, PRIMARY KEY (topic) -) +); From shino at rubyforge.org Thu Aug 30 20:51:37 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 30 Aug 2007 20:51:37 -0400 (EDT) Subject: [ap4r-devel] [281] branches/200709_gihyo/async_shop/as_rails/log: remove log files from version control Message-ID: <20070831005137.8286B5240DC7@rubyforge.org> Revision: 281 Author: shino Date: 2007-08-30 20:51:35 -0400 (Thu, 30 Aug 2007) Log Message: ----------- remove log files from version control Removed Paths: ------------- branches/200709_gihyo/async_shop/as_rails/log/production.log branches/200709_gihyo/async_shop/as_rails/log/server.log Deleted: branches/200709_gihyo/async_shop/as_rails/log/production.log =================================================================== Deleted: branches/200709_gihyo/async_shop/as_rails/log/server.log =================================================================== From shino at rubyforge.org Thu Aug 30 20:55:54 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 30 Aug 2007 20:55:54 -0400 (EDT) Subject: [ap4r-devel] [282] branches/200709_gihyo/async_shop/as_rails/test/async/async_shop_test.rb: remove a test which fails (intentionally) Message-ID: <20070831005554.C9BF85240DC7@rubyforge.org> Revision: 282 Author: shino Date: 2007-08-30 20:55:54 -0400 (Thu, 30 Aug 2007) Log Message: ----------- remove a test which fails (intentionally) Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/test/async/async_shop_test.rb Modified: branches/200709_gihyo/async_shop/as_rails/test/async/async_shop_test.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/async/async_shop_test.rb 2007-08-31 00:51:35 UTC (rev 281) +++ branches/200709_gihyo/async_shop/as_rails/test/async/async_shop_test.rb 2007-08-31 00:55:54 UTC (rev 282) @@ -24,10 +24,6 @@ end - def test_just_fail - assert false - end - private # Requests to async_shop/order. From shino at rubyforge.org Thu Aug 30 20:58:43 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 30 Aug 2007 20:58:43 -0400 (EDT) Subject: [ap4r-devel] [283] branches/200709_gihyo/async_shop/as_rails/: add svn:ignore Message-ID: <20070831005843.A03B85240DC2@rubyforge.org> Revision: 283 Author: shino Date: 2007-08-30 20:58:43 -0400 (Thu, 30 Aug 2007) Log Message: ----------- add svn:ignore Property Changed: ---------------- branches/200709_gihyo/async_shop/as_rails/ Property changes on: branches/200709_gihyo/async_shop/as_rails ___________________________________________________________________ Name: svn:ignore - + .autotest From shino at rubyforge.org Thu Aug 30 21:02:05 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 30 Aug 2007 21:02:05 -0400 (EDT) Subject: [ap4r-devel] [284] branches/200709_gihyo/async_shop/as_rails: extrace Rails and AP4R service handlers from a test helper into the plugin library. Message-ID: <20070831010205.399305240DC2@rubyforge.org> Revision: 284 Author: shino Date: 2007-08-30 21:02:04 -0400 (Thu, 30 Aug 2007) Log Message: ----------- extrace Rails and AP4R service handlers from a test helper into the plugin library. Hadlers functinals - Start and stop Rails/AP4R processes - Start and stop AP4R's dispathcers - Wait until no active messages in AP4R service - etc. Needs more work :-) Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/test/async/ap4r_test_helper.rb branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb Modified: branches/200709_gihyo/async_shop/as_rails/test/async/ap4r_test_helper.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/test/async/ap4r_test_helper.rb 2007-08-31 00:58:43 UTC (rev 283) +++ branches/200709_gihyo/async_shop/as_rails/test/async/ap4r_test_helper.rb 2007-08-31 01:02:04 UTC (rev 284) @@ -4,9 +4,9 @@ ENV["RAILS_ENV"] = "test" require File.expand_path(File.dirname(__FILE__) + "/../../config/environment") -require "ap4r/service_handler.rb" +require "ap4r/service_handler" -ap4r_test_helper = Ap4rTestHelper.new +ap4r_test_helper = Ap4r::ServiceHandler.new # ap4r_test_helper.start_rails_service # at_exit { ap4r_test_helper.stop_rails_service } Modified: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb 2007-08-31 00:58:43 UTC (rev 283) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb 2007-08-31 01:02:04 UTC (rev 284) @@ -2,160 +2,164 @@ # Copyright:: Copyright (c) 2007 Future Architect Inc. # Licence:: MIT Licence +require 'rubygems' require 'erb' require 'yaml' require 'reliable-msg' require 'ap4r' +require 'timeout' -class Ap4rTestHelper +module Ap4r - def initialize(config_file = RAILS_ROOT + "/config/test_async.yml") - raise "please create config/async_test.yml to configure ap4r service." unless File.exist?(config_file) + class ServiceHandler - config = {} - File.open(config_file, "r") do |input| - YAML.load_documents(ERB.new(input.read).result) do |doc| - config.merge! doc + def initialize(config_file = RAILS_ROOT + "/config/test_async.yml") + raise "please create config/async_test.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["ap4r"] + @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 - @test_config = config["ap4r"] - @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 - 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 " + + "start -d -c #{@root_dir} -A #{@config_file} -p 13038" + message = "Starting Mongrel(AP4R)" + execute_command(command, message, false) + if wait_until_started + print "and waiting..." + wait_until_alive + end + puts "Done." + end - # Starts ap4r service. - def start_ap4r_service(wait_until_started = true) - command = "ruby #{@test_config["start_ruby_args"]} #{@root_dir}/script/mongrel_ap4r " + - "start -d -c #{@root_dir} -A #{@config_file} -p 13038" - message = "Starting Mongrel(AP4R)" - execute_command(command, message, false) - if wait_until_started - print "and waiting..." - wait_until_alive + # Stops ap4r service. + def stop_ap4r_service + command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r " + + "stop -c #{@root_dir}" + message = "Terminating Mongrel(AP4R)" + execute_command(command, message, false) + @qm = nil end - puts "Done." - end - # Stops ap4r service. - def stop_ap4r_service - command = "ruby #{@test_config["stop_ruby_args"]} #{@root_dir}/script/mongrel_ap4r " + - "stop -c #{@root_dir}" - 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 - # 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 - - require 'timeout' - # Stops rails service. - def stop_rails_service -# puts "read pid" -# pid = File.read('log/mongrel.pid').to_i -# puts "send signal to #{pid}" -# Process.kill(:TERM, `cat log/mongrel.pid`.to_i) -# puts "done" -# return - command = "mongrel_rails stop" -# command = "kill " + `cat log/mongrel.pid` - command = "sh -c 'mongrel_rails stop'" - message = "Terminating Mongrel(Rails)" - begin - timeout(5) do - execute_command(command, message, false) - end - rescue TimeoutError - puts "!!! command timed out !!!" + # Stops rails service. + def stop_rails_service + # puts "read pid" + # pid = File.read('log/mongrel.pid').to_i + # puts "send signal to #{pid}" + # Process.kill(:TERM, `cat log/mongrel.pid`.to_i) + # puts "done" + # return + command = "mongrel_rails stop" + # command = "kill " + `cat log/mongrel.pid` + # command = "sh -c 'mongrel_rails stop'" + message = "Terminating Mongrel(Rails)" + execute_command(command, message, false) end - end - # Starts rails service and ap4r service. - # After block execution, stops both. - def with_services - begin - start_rails_service + # Starts rails service and ap4r service. + # After block execution, stops both. + def with_services begin - start_ap4r_service - yield + start_rails_service + begin + start_ap4r_service + yield + ensure + stop_ap4r_service + end ensure - stop_ap4r_service + stop_rails_service end - ensure - stop_rails_service end - end - def start_dispatchers - qm.dispatchers.start - end + def start_dispatchers + qm.dispatchers.start + end - def stop_dispatchers - qm.dispatchers.stop - end + def stop_dispatchers + qm.dispatchers.stop + end - def clear(*queues) - raise "not yet implemented" - queues.each do |queue| - q = ReliableMsg::Queue.new(queue) - loop do - break unless q.get + 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 - 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 + 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 - end - def wait_all_done - 50.times do - break if flag = qm.no_active_message? - sleep 0.2 + def wait_all_done + 50.times do + break if flag = qm.no_active_message? + sleep 0.2 + end end - end - def dlq - qm.list :queue => "$dlq" - end + def dlq + qm.list :queue => "$dlq" + end - private - def execute_command(command, message, with_done_message = true) -# print "#{message} with command: #{command}..." - result = system(command, "") - # TODO: handle result 2007/08/29 by shino - puts "Done." if with_done_message - end - - def wait_until_alive(message = nil) - 50.times do - print message if message + private + def execute_command(command, message, with_done_message = true) + command += ";" # force to execute via shell + print "#{message} with command: #{command}..." begin - break if qm.alive? - rescue => e - # ignore + timeout(10) do + result = system("#{command}") + # TODO: handle result 2007/08/29 by shino + puts "Done." if with_done_message + end + rescue TimeoutError + puts "!!! command timed out !!!" end - sleep 0.2 end + + def wait_until_alive(message = nil) + 50.times do + print message if message + begin + break if qm.alive? + rescue => e + # ignore + end + sleep 0.2 + end + end end - end From shino at rubyforge.org Thu Aug 30 21:03:54 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 30 Aug 2007 21:03:54 -0400 (EDT) Subject: [ap4r-devel] [285] branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake: add rake tasks to start/stop AP4R and Rails processes Message-ID: <20070831010354.27EDD5240DC2@rubyforge.org> Revision: 285 Author: shino Date: 2007-08-30 21:03:53 -0400 (Thu, 30 Aug 2007) Log Message: ----------- add rake tasks to start/stop AP4R and Rails processes Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake Modified: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake 2007-08-31 01:02:04 UTC (rev 284) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/tasks/ap4r.rake 2007-08-31 01:03:53 UTC (rev 285) @@ -1,3 +1,5 @@ +require File.expand_path(File.dirname(__FILE__) + "/../lib/ap4r/service_handler.rb") + namespace :test do # task :asyncs do @@ -6,11 +8,21 @@ # end namespace :asyncs do + desc "Start Rails and AP4R servers to test:asyncs:exec" - task :setup do |t| - puts "setup task should be implemented here" + task :arrange do |t| + ap4r_handler = Ap4r::ServiceHandler.new + ap4r_handler.start_rails_service + ap4r_handler.start_ap4r_service end + desc "Start Rails and AP4R servers to test:asyncs:exec" + task :cleanup do |t| + ap4r_handler = Ap4r::ServiceHandler.new + ap4r_handler.stop_ap4r_service + ap4r_handler.stop_rails_service + end + Rake::TestTask.new(:run => "db:test:prepare") do |t| t.libs << "test" t.pattern = 'test/async/**/*_test.rb' From shino at rubyforge.org Thu Aug 30 22:11:17 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 30 Aug 2007 22:11:17 -0400 (EDT) Subject: [ap4r-devel] [286] branches/200709_gihyo/async_shop/as_rails/config: change file name to include only generic settings Message-ID: <20070831021117.A2A915240DD2@rubyforge.org> Revision: 286 Author: shino Date: 2007-08-30 22:11:17 -0400 (Thu, 30 Aug 2007) Log Message: ----------- change file name to include only generic settings Added Paths: ----------- branches/200709_gihyo/async_shop/as_rails/config/test_async.sample.yml Removed Paths: ------------- branches/200709_gihyo/async_shop/as_rails/config/test_async.yml Copied: branches/200709_gihyo/async_shop/as_rails/config/test_async.sample.yml (from rev 285, branches/200709_gihyo/async_shop/as_rails/config/test_async.yml) =================================================================== --- branches/200709_gihyo/async_shop/as_rails/config/test_async.sample.yml (rev 0) +++ branches/200709_gihyo/async_shop/as_rails/config/test_async.sample.yml 2007-08-31 02:11:17 UTC (rev 286) @@ -0,0 +1,5 @@ +--- +ap4r: + root_dir: ../as_ap4r + config_file: config/queues_test.cfg +rails: Deleted: branches/200709_gihyo/async_shop/as_rails/config/test_async.yml =================================================================== --- branches/200709_gihyo/async_shop/as_rails/config/test_async.yml 2007-08-31 01:03:53 UTC (rev 285) +++ branches/200709_gihyo/async_shop/as_rails/config/test_async.yml 2007-08-31 02:11:17 UTC (rev 286) @@ -1,7 +0,0 @@ ---- -ap4r: - root_dir: ../as_ap4r - config_file: config/queues_test.cfg - start_ruby_args: -I ~/d/ap4r-core-trunk/lib - stop_ruby_args: -I ~/d/ap4r-core-trunk/lib -rails: From shino at rubyforge.org Thu Aug 30 22:12:41 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Thu, 30 Aug 2007 22:12:41 -0400 (EDT) Subject: [ap4r-devel] [287] branches/200709_gihyo/async_shop/as_rails/config/: add svn:ignore Message-ID: <20070831021242.3D0265240DD9@rubyforge.org> Revision: 287 Author: shino Date: 2007-08-30 22:12:40 -0400 (Thu, 30 Aug 2007) Log Message: ----------- add svn:ignore Property Changed: ---------------- branches/200709_gihyo/async_shop/as_rails/config/ Property changes on: branches/200709_gihyo/async_shop/as_rails/config ___________________________________________________________________ Name: svn:ignore + test_async.yml From shino at rubyforge.org Fri Aug 31 02:43:35 2007 From: shino at rubyforge.org (shino at rubyforge.org) Date: Fri, 31 Aug 2007 02:43:35 -0400 (EDT) Subject: [ap4r-devel] [288] branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb: Fix: file name typo Message-ID: <20070831064335.27BBC5240E0C@rubyforge.org> Revision: 288 Author: shino Date: 2007-08-31 02:43:33 -0400 (Fri, 31 Aug 2007) Log Message: ----------- Fix: file name typo Modified Paths: -------------- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb Modified: branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb =================================================================== --- branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb 2007-08-31 02:12:40 UTC (rev 287) +++ branches/200709_gihyo/async_shop/as_rails/vendor/plugins/ap4r/lib/ap4r/service_handler.rb 2007-08-31 06:43:33 UTC (rev 288) @@ -14,7 +14,7 @@ class ServiceHandler def initialize(config_file = RAILS_ROOT + "/config/test_async.yml") - raise "please create config/async_test.yml to configure ap4r service." unless File.exist?(config_file) + raise "please create config/test_async.yml to configure ap4r service." unless File.exist?(config_file) config = {} File.open(config_file, "r") do |input| From kato-k at rubyforge.org Fri Aug 31 04:22:27 2007 From: kato-k at rubyforge.org (kato-k at rubyforge.org) Date: Fri, 31 Aug 2007 04:22:27 -0400 (EDT) Subject: [ap4r-devel] [289] trunk/ap4r/Rakefile: Modified: removed Hoe as a dependency. Message-ID: <20070831082228.1ACC25240E71@rubyforge.org> Revision: 289 Author: kato-k Date: 2007-08-31 04:22:22 -0400 (Fri, 31 Aug 2007) Log Message: ----------- Modified: removed Hoe as a dependency. Modified Paths: -------------- trunk/ap4r/Rakefile Modified: trunk/ap4r/Rakefile =================================================================== --- trunk/ap4r/Rakefile 2007-08-31 06:43:33 UTC (rev 288) +++ trunk/ap4r/Rakefile 2007-08-31 08:22:22 UTC (rev 289) @@ -41,7 +41,7 @@ p.test_globs = 'spec/**/*_spec.rb' p.url = 'http://ap4r.rubyforge.org/wiki/wiki.pl?HomePage' p.version = Ap4r::VERSION::STRING -end +end.spec.dependencies.delete_if {|dep| dep.name == "hoe"} desc 'Create Manifest.txt'