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) Dat