ap4r 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,6 +1,10 @@
1
- CHANGELOG
1
+ == 0.1.x
2
2
 
3
- == 0.1.0
3
+ === 0.1.1 (October 5th, 2006)
4
4
 
5
- * Initial release.
5
+ * Changed: Enriched RDoc.
6
+ * Changed: Enriched README.
7
+
8
+ === 0.1.0 (September 1st, 2006)
6
9
 
10
+ * Initial release.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006 ???
1
+ Copyright (c) 2006 Future System Consulting Corp.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README CHANGED
@@ -1,52 +1,196 @@
1
- We are pleased to announce the FIRST release of AP4R.
2
-
3
- http://rubyforge.org/projects/ap4r/
4
-
5
-
6
- == DESCRIPTION
7
-
8
- AP4R, Asynchronous Processing for Ruby, is the implementation of
9
- reliable asynchous message processing.
10
-
11
-
12
- Using asynchronous processing, we can cut down turn-around-time
13
- of web applications by queuing, or can utilize more machine power
14
- by load-balancing.
15
-
16
- AP4R provides message queuing, and message dispatching.
17
- Also AP4R nicely ties with your Ruby on Rails applications.
18
-
19
-
20
- == INSTALLATION
21
-
22
- sudo gem install ap4r
23
-
24
-
25
- == FEATURES
26
-
27
- * Business logics can be implemented as simple Web apps, or ruby code,
28
- whether it's called asynchronously or synchronously.
29
-
30
- * Asynchronous messaging are reliable
31
- by PersistRDBMS (now MySQL only) or file persistence.
32
-
33
- * Load balancing over multiple AP4R processes on single/multiple servers
34
- is supported.
35
-
36
- * Asynchronous processing is via various protocols, such as XML-RPC, SOAP,
37
- HTTP PUT, and more. (now implemented just as XML-RPC)
38
-
39
-
40
- == CHANGES
41
-
42
- This is the first release!
43
-
44
-
45
- == ACKNOWLEDGEMENT
46
-
47
- K.K. and S.S. are on the payroll of Future System Consulting Corp. Japan.
48
-
49
-
50
- --
51
- Kato, Kiwamu kato.kiwamu@future.co.jp
52
- Shinohara, Shunichi shinohara.shunichi@future.co.jp
1
+ == What is AP4R?
2
+
3
+ AP4R, Asynchronous Processing for Ruby, is the implementation of reliable asynchronous message processing. It provides message queuing, and message dispatching.
4
+ Using asynchronous processing, we can cut down turn-around-time of web applications by queuing, or can utilize more machine power by load-balancing.
5
+ Also AP4R nicely ties with your Ruby on Rails applications. See Hello World sample application from rubyforge.
6
+
7
+ http://rubyforge.org/projects/ap4r/
8
+
9
+ == Features
10
+
11
+ 1. Business logics can be implemented as simple Web applications, or ruby code, whether it's called asynchronously or synchronously.
12
+ 1. Asynchronous messaging is reliable by RDBMS persistence (now MySQL only) or file persistence, under the favor of reliable-msg.
13
+ 1. Load balancing over multiple AP4R processes on single/multiple servers is supported.
14
+ 1. Asynchronous logics are called via various protocols, such as XML-RPC, SOAP, HTTP PUT, and more. (now implemented just as XML-RPC)
15
+
16
+ == Typical process flow
17
+
18
+ 1. A client(e.g. a web browser) makes a request to a web server (Apache, Lighttpd, etc...).
19
+ 1. A rails application (a synchronous logic) is executed on mongrel via mod_proxy or something.
20
+ 1. At the last of the synchronous logic, message(s) are put to AP4R (AP4R provides a helper).
21
+ 1. Once the synchronous logic is done, the clients receives a response immediately.
22
+ 1. AP4R queues the message, and requests it to the web server asynchronously.
23
+ 1. An asynchronous logic, implemented as usual rails action, is executed.
24
+
25
+
26
+ == Installation
27
+
28
+ Use RubyGems command.
29
+
30
+ $ sudo gem install ap4r --include-dependencies
31
+
32
+
33
+ == Working directory
34
+
35
+ Create your working directory (ex. my_work) wherever you want.
36
+
37
+ $ ap4r_setup my_work
38
+ $ cd my_work
39
+
40
+ Its structure is as follows.
41
+
42
+ my_work
43
+ +-- config
44
+ +-- log
45
+ +-- script
46
+ +-- tmp
47
+
48
+ == Message Persistence
49
+
50
+ AP4R uses reliable-msg for message persistence. It enables disk or RDBMS persistence. See references for details of reliable-msg. Install MySQL if you choose MySQL persistence. We recommend to install MySQL/Ruby library to connect to MySQL. For convinience, Ruby/MySQL bundled in the ActiveRecord gem can be used.
51
+ Create a table in your database. (If you use topics via reliable-msg, create another slightly different table.)
52
+
53
+ CREATE TABLE `reliable_msg_queues` (
54
+ `id` varchar(255) NOT NULL default '',
55
+ `queue` varchar(255) NOT NULL default '',
56
+ `headers` text NOT NULL,
57
+ `object` blob NOT NULL,
58
+ PRIMARY KEY (`id`)
59
+ ) ENGINE=InnoDB DEFAULT CHARSET=binary;
60
+
61
+ == Configuration file
62
+
63
+ A command ap4r_setup have created a template configuration file (my_work/config/queues.cfg).
64
+
65
+ ---
66
+ store:
67
+ type: mysql
68
+ host: localhost
69
+ database: test
70
+ username: test
71
+ password:
72
+ drb:
73
+ host:
74
+ port: 6438
75
+ acl: allow 127.0.0.1
76
+ dispatchers:
77
+ -
78
+ targets: queue.*
79
+ threads: 1
80
+ #carriers:
81
+ # -
82
+ # source_uri: druby://another.host.local:6438
83
+ # threads: 1
84
+
85
+ queues.cfg has four parts.
86
+
87
+ * persistent role (store: )
88
+ * Set database or file information.
89
+
90
+ * message listener (drb:)
91
+ * Set IP, and port number which are used by clients.
92
+ * acl = access control list, exmaple below.
93
+
94
+ allow 127.0.0.1 allow 10.0.0.0/8 deny 192.168.0.1
95
+
96
+ * asynchronous process invokers (dispatchers:)
97
+ * Dispatchers handle messages in queues specified by targets,
98
+ * with as many threads as specified by threads.
99
+ * Each thread waits (is blocked) until the invocation returns.
100
+
101
+ * message routing (carriers:) # EXPERIMENTAL
102
+ * Carriers get messages from an AP4R server specified by source_uri,
103
+ * with as many threads as specified by threads,
104
+ * and put messages to a local AP4R server.
105
+
106
+ == Monitoring
107
+
108
+ Future plan: connections with monitoring tools such as Cacti and ZABBIX.
109
+
110
+ * Cacti
111
+ * http://www.cacti.net/
112
+ * ZABBIX
113
+ * http://www.zabbix.org/
114
+
115
+ == Sample - HelloWorld -
116
+
117
+ There is an asynchronous application sample with file persistence, where a synchronous logic outputs "Hello" to a file, and an asynchronous logic appends "World".
118
+ Once the synchronous logic has done, a client (a web browser) displays response, and there is only "Hello" in a file.
119
+ Since the asynchronous logic sleeps ten seconds and appends to the file, wait briefly and you can see whole "HelloWorld" in the file
120
+
121
+ * Install Ruby, Rails and AP4R and configure AP4R in reference above sections
122
+ * No need for MySQL.
123
+
124
+ * Make sample application available
125
+ * If you have an SVN client,
126
+
127
+ $ svn co svn://rubyforge.org/var/ap4r/tags/ap4r-0.1.0/sample [some directory]
128
+
129
+ * Unless
130
+ 1. download the sample from RubyForge
131
+ http://rubyforge.org/projects/ap4r/
132
+ filename: HelloWorld.zip
133
+
134
+ 1. and extract to an appropricate directory(ex. HelloWorld ).
135
+ There are app/, components/,... directories under HelloWorld.
136
+
137
+ * Start WEBRick.
138
+ * In a command line
139
+
140
+ $ cd HelloWorld
141
+ $ ruby script\server
142
+
143
+ * If you see Welcome screen at http://localhost:3000, it's ok.
144
+
145
+ * Start AP4R.
146
+ * In another command line,
147
+ * start AP4R with specifying the configuraion file.
148
+
149
+ $ cd my_work
150
+ $ ruby script/start -c config/queues_disk.cfg
151
+
152
+ * Execute a synchronous logic.
153
+ * http://localhost:3000/sync_hello/execute
154
+ * A file HelloWorld.txt is creted under HelloWorld/ which contains a word "Hello".
155
+
156
+ * Confirm the execution of an asynchronous logic.
157
+ * Wait ten seconds,
158
+ * and look into the file HelloWorld.txt again, there must be "HelloWorld".
159
+
160
+ * Think of application to your real application
161
+ * This mechanism can work in general applications.
162
+ * An order acceptance logic instead of printing "Hello".
163
+ * Asynchronous logic of auto shipping order or accounting instead of appending "World".
164
+
165
+ == Future Plan
166
+
167
+ * add protocols to invoke asynchronous logics
168
+ * only-once QoS
169
+ * at-lease-once QoS
170
+ * DLQ recovery
171
+ * flow volume control, load balancing
172
+ * 7x24 support (e.g. rolling database tables)
173
+ * monitoring (e.g. thread status, web frontend)
174
+ * Coordination with Ruby on Rails, such as development/testing lifesycle support.
175
+
176
+ == References
177
+
178
+ * Ruby Homepage
179
+ * http://www.ruby-lang.org/
180
+ * Ruby on Rails tutorial
181
+ * http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html
182
+ * MySQL tutorial
183
+ * http://dev.mysql.com/doc/refman/5.0/en/index.html
184
+ * reliable-msg
185
+ * http://trac.labnotes.org/cgi-bin/trac.cgi/wiki/Ruby/ReliableMessaging
186
+
187
+ == Licence
188
+
189
+ This licence is licensed under the MIT license.
190
+ Copyright(c) 2006 Future System Consulting Corp.
191
+
192
+ == Authors
193
+
194
+ * Kiwamu Kato
195
+ * Shunichi Shinohara
196
+
data/Rakefile CHANGED
@@ -1,25 +1,143 @@
1
- require 'rubygems'
1
+ # Author:: Kiwamu Kato
2
+ # Copyright:: Copyright (c) 2006 Future System Consulting Corp.
3
+ # Licence:: MIT Licence
4
+
2
5
  require 'rake'
3
6
  require 'rake/testtask'
4
7
  require 'rake/rdoctask'
5
- require 'rake/packagetask'
6
8
  require 'rake/gempackagetask'
7
9
  require 'rake/contrib/rubyforgepublisher'
8
10
 
9
- Gem::Specification.new do |s|
10
- s.name = %q{orca}
11
- s.version = "0.1.0"
12
- s.date = %q{2006-05-18}
13
- s.summary = %q{Messageing library with Rails for asynchronous process.}
14
- s.email = %q{kato.kiwamu@future.co.jp}
15
- s.homepage = %q{http://orca2.rtfa.local/orca/}
16
- s.rubyforge_project = %q{}
17
- s.description = %q{Messageing library with Rails for asynchronous proces.}
18
- s.autorequire = %q{orca}
11
+ require 'date'
12
+ require 'find'
13
+ require 'rbconfig'
14
+
15
+ require File.join(File.dirname(__FILE__), 'lib/ap4r', 'version')
16
+
17
+ PKG_VERSION = AP4R::VERSION::STRING
18
+
19
+ TEMP_DIR = './temp'
20
+ PKG_DIR = './pkg'
21
+ RELEASE_DIR = './release'
22
+ HELLO_WORLD_DIR = '../samples/HelloWorld'
23
+
24
+ # Generate GEM ----------------------------------------------------------------------------
25
+
26
+
27
+ PKG_FILES = FileList[
28
+ '[a-zA-Z]*',
29
+ 'bin/**/*',
30
+ 'config/**/*',
31
+ 'rails_plugin/**/*',
32
+ 'script/**/*',
33
+ 'lib/**/*'
34
+ ]
35
+
36
+ HELLO_WORLD_SAMPLE_FILES = FileList[
37
+ '[a-zA-Z]*',
38
+ 'app/**/*',
39
+ 'components/**/*',
40
+ 'config/**/*',
41
+ 'db/**/*',
42
+ 'doc/**/*',
43
+ 'lib/**/*',
44
+ 'log/**/*',
45
+ 'public/**/*',
46
+ 'script/**/*',
47
+ 'test/**/*',
48
+ 'tmp/**/*',
49
+ 'vendor/**/*',
50
+ ]
51
+
52
+
53
+ spec = Gem::Specification.new do |s|
54
+ s.name = 'ap4r'
55
+ s.version = PKG_VERSION
56
+ s.summary = "Asynchronous Processing for Ruby."
57
+ s.description = <<-EOF
58
+ Asynchronous Processing for Ruby.
59
+ EOF
60
+
61
+ s.add_dependency(%q<reliable-msg>, ["= 1.1.0"])
62
+
19
63
  s.has_rdoc = true
20
- s.authors = ["Shino,Kato"]
21
- s.files = Dir.glob("{script,lib,logs,utils}/**/*") << "CHANGELOG" << "log4r.yaml" << "MIT-LICENSE" << "queues.cfg" << "queues1.cfg" << "queues2.cfg" << "Rakefile" << "README"
22
- s.requirements = ["none"]
64
+ s.extra_rdoc_files = ["README", "CHANGELOG", 'rails_plugin']
65
+ s.rdoc_options << "--main" << "README"
66
+ s.rdoc_options << "--title" << "Asynchronous Processing for Ruby"
67
+ s.rdoc_options << "--line-numbers"
68
+
69
+
70
+ s.files = PKG_FILES.to_a.delete_if {|f| f.include?('.svn')}
71
+ s.require_path = 'lib'
72
+ s.autorequire = %q{ap4r.rb}
73
+
74
+ s.bindir = "bin" # Use these for applications.
75
+ s.executables = ["ap4r_setup"]
76
+ s.default_executable = "ap4r_setup"
77
+
78
+ s.authors = ["Shunichi Shinohara", "Kiwamu Kato"]
79
+ s.email = %q{shinohara.shunichi@future.co.jp, kato.kiwamu@future.co.jp}
80
+ s.homepage = %q{http://rubyforge.org/projects/ap4r/}
81
+ s.rubyforge_project = "ap4r"
82
+ end
83
+
84
+ Rake::GemPackageTask.new(spec) do |pkg|
23
85
  end
24
86
 
87
+ # Generate documentation ------------------------------------------------------------------
88
+
89
+ Rake::RDocTask.new { |rdoc|
90
+ rdoc.rdoc_dir = 'doc'
91
+ rdoc.options << '--line-numbers' << '--inline-source' << '--accessor' << 'cattr_accessor=rw'
92
+ rdoc.rdoc_files.include('README', 'CHANGELOG')
93
+ rdoc.rdoc_files.include('lib/**/*.rb')
94
+ rdoc.rdoc_files.include('rails_plugin/**/*.rb')
95
+ }
96
+
97
+ # AP4R release ----------------------------------------------------------------
98
+
99
+ desc "Make gem and sample tgz"
100
+ task :release => [ :make_release_dir, :make_sample_tgz, :copy_to_release_dir ]
101
+
102
+ task :make_sample_tgz => [ :make_temp_dir, :copy_sample, :make_tgz ]
103
+
104
+ task :make_release_dir do
105
+ make_dir RELEASE_DIR
106
+ end
107
+
108
+ task :make_temp_dir do
109
+ make_dir TEMP_DIR
110
+ end
111
+
112
+ def make_dir(path)
113
+ if(File.exist?(path))
114
+ FileUtils.remove_entry(path, true)
115
+ end
116
+ FileUtils.mkdir_p(path)
117
+ end
118
+
119
+
120
+ task :copy_sample do
121
+ FileUtils.cp_r(HELLO_WORLD_DIR, TEMP_DIR)
122
+ Find.find(TEMP_DIR) {|f|
123
+ if f.include?('.svn')
124
+ FileUtils.rm_rf(f)
125
+ end
126
+ }
127
+ end
128
+
129
+ task :make_tgz do
130
+ Dir.chdir('temp/')
131
+ `tar czvf HelloWorld.tar.gz HelloWorld/`
132
+ Dir.chdir('../')
133
+ end
134
+
135
+ task :copy_to_release_dir do
136
+ Dir.foreach(PKG_DIR) {|f|
137
+ FileUtils.cp(PKG_DIR + '/' + f, RELEASE_DIR) if File.fnmatch("*.gem", f)
138
+ }
139
+ Dir.foreach(TEMP_DIR) {|f|
140
+ FileUtils.cp(TEMP_DIR + '/' + f, RELEASE_DIR) if File.fnmatch("*.tar.gz", f)
141
+ }
142
+ end
25
143
 
data/bin/ap4r_setup ADDED
@@ -0,0 +1,6 @@
1
+ Signal.trap("INT") { puts; exit }
2
+
3
+ require File.dirname(__FILE__) + '/../lib/ap4r/script/setup'
4
+
5
+ require 'ap4r/script/workspace_generator'
6
+ AP4R::Script::WorkspaceGenerator.new.run(ARGV, :generator => 'app')
@@ -0,0 +1,5 @@
1
+ AP4R::Configuration.setup {|services|
2
+ services.add 'queues_disk.cfg', :host => 'localhost', :name => :rm1
3
+ # services.add 'queues.cfg', :name => :rm2
4
+ }
5
+
File without changes
File without changes