reliable-msg 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005 Assaf Arkin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,123 @@
1
+ = Reliable Messaging for Ruby
2
+
3
+ This package provides reliable messaging and persistent queues for
4
+ building asynchronous applications in Ruby.
5
+
6
+ This release provides the following features:
7
+
8
+ * Simple API.
9
+
10
+ * Transction processing.
11
+
12
+ * Disk-based and MySQL message stores.
13
+
14
+ * Best effort, repeated and once-only delivery semantics.
15
+
16
+ * Priority queues, message expiration, dead-letter queue.
17
+
18
+ * Message selectors.
19
+
20
+ * Local and remote queue managers using DRb.
21
+
22
+
23
+ == Download
24
+
25
+ The latest version of Reliable Messaging can be found at
26
+
27
+ * http://rubyforge.org/projects/reliable-msg/
28
+
29
+ For more information (wiki, bug reports)
30
+
31
+ * http://trac.labnotes.org/cgi-bin/trac.cgi/wiki/RubyReliableMessaging
32
+
33
+
34
+ == Installation
35
+
36
+ You can download the sources directly, or install the GEM package
37
+ (recommended) with
38
+
39
+ gem install --remote reliable-msg
40
+
41
+ To create the configuration file and queues for use with the disk-based
42
+ message store
43
+
44
+ queues install disk [<path>]
45
+
46
+ The optional <tt>path</tt> argument specifies the directory in which
47
+ queue index and messages are store. The default directory is
48
+ <tt>queues</tt>.
49
+
50
+ To create the configuration file and queues for use with the MySQL
51
+ message store
52
+
53
+ queues install mysql <host> <user> <password> <database>
54
+ [--port <port>] [--socket <socket>] [--prefix <prefix>]
55
+
56
+ You must have MySQL libraries installed in order to use this message
57
+ store, either native MySQL libraries or the Rails pure-Ruby adapter.
58
+ It uses the supplied connection properties and creates tables in your
59
+ database using the specified prefix. The default prefix is
60
+ <tt>reliable_msg_</tt>.
61
+
62
+ For example
63
+
64
+ queues install mysql localhost my-db user secret
65
+
66
+ === Configuration file
67
+
68
+ The installation process creates a configuration file
69
+ (<tt>queues.cfg</tt>) located in the same directory as the library.
70
+ You can specify a different location for the configuration file using
71
+ the option <tt>-c</tt> of <tt>--config</tt>.
72
+
73
+ When you use the queue manager, it looks for a specified configuration
74
+ file, or if no configuration file is specified it looks for the
75
+ <tt>queues.cfg</tt> file, first in the local directory and then in the
76
+ installation directory. If no file exists, it will create a default one
77
+ to use the disk-based message store.
78
+
79
+ === UUID state file
80
+
81
+ Reliable messaging requires a UUID generator that is able to create
82
+ universally unique identifiers. The UUID generator uses the
83
+ <tt>uuid.state</tt> file to hold a unique machine identifier and a
84
+ rolling sequence number.
85
+
86
+ On the first usage, a <tt>uuid.state</tt> file is created in the
87
+ installation directory. An existing state file will be used if one
88
+ exists in the local directory or the installation directory.
89
+
90
+ The unique machine identifier is obtained from one of the network
91
+ card's MAC address on your machine, using either the +ipconfig+ or
92
+ +ifconfig+ commands. If no MAC address can be found, or you want to
93
+ pick a specific MAC address, create a <tt>uuid.state</tt> file
94
+ manually.
95
+
96
+
97
+ == Simple Example
98
+
99
+ Start the queue manager as a standalone server
100
+
101
+ queues manager start
102
+
103
+ Use the queue API in your application
104
+
105
+ require 'reliable-msg'
106
+
107
+ queue = Queue.new 'my-queue'
108
+ queue.put obj
109
+ msg = queue.get
110
+ assert msg.object == obj
111
+
112
+ Stop the queue manager
113
+
114
+ queues manager stop
115
+
116
+
117
+ == License
118
+
119
+ This package is licensed under the MIT license and/or the {Creative
120
+ Commons Attribution-ShareAlike}[http://creativecommons.org/licenses/by-sa/2.5/legalcode].
121
+
122
+ :include: MIT-LICENSE
123
+
@@ -0,0 +1,164 @@
1
+ # Adapted from the rake Rakefile.
2
+
3
+ require 'rubygems'
4
+ Gem::manage_gems
5
+ require 'rake/testtask'
6
+ require 'rake/rdoctask'
7
+ require 'rake/gempackagetask'
8
+
9
+
10
+ desc "Default Task"
11
+ task :default => [:tests, :rdoc]
12
+
13
+
14
+ desc "Run test case for UUID generator"
15
+ Rake::TestTask.new :test_uuid do |test|
16
+ test.verbose = true
17
+ test.test_files = ['test/test-uuid.rb']
18
+ end
19
+ desc "Run test case for Queue API generator"
20
+ Rake::TestTask.new :test_queue do |test|
21
+ test.verbose = true
22
+ test.test_files = ['test/test-queue.rb']
23
+ end
24
+ desc "Run all test cases"
25
+ Rake::TestTask.new :tests=>[:test_uuid, :test_queue] do |test|
26
+ test.verbose = true
27
+ test.test_files = []
28
+ #test.warning = true
29
+ end
30
+
31
+
32
+ # Create the documentation.
33
+ Rake::RDocTask.new do |rdoc|
34
+ rdoc.main = "README"
35
+ rdoc.rdoc_files.include("README", "lib/**/*.rb")
36
+ rdoc.title = 'Reliable Messaging'
37
+ end
38
+
39
+ # Handle version number.
40
+ class Version
41
+
42
+ PATTERN = /(\s*)VERSION.*(\d+\.\d+\.\d+)/
43
+
44
+ def initialize file, new_version
45
+ @file = file
46
+ @version = File.open @file, 'r' do |file|
47
+ version = nil
48
+ file.each_line do |line|
49
+ match = line.match PATTERN
50
+ if match
51
+ version = match[2]
52
+ break
53
+ end
54
+ end
55
+ version
56
+ end
57
+ fail "Can't determine version number" unless @version
58
+ @new_version = new_version || @version
59
+ end
60
+
61
+ def changed?
62
+ @version != @new_version
63
+ end
64
+
65
+ def number
66
+ @version
67
+ end
68
+
69
+ def next
70
+ @new_version
71
+ end
72
+
73
+ def update
74
+ puts "Updating to version #{@new_version}"
75
+ copy = "#{@file}.new"
76
+ open @file, "r" do |input|
77
+ open copy, "w" do |output|
78
+ input.each_line do |line|
79
+ match = line.match PATTERN
80
+ if match
81
+ output.puts "#{match[1]}VERSION = '#{@new_version}'"
82
+ else
83
+ output.puts line
84
+ end
85
+ end
86
+ end
87
+ end
88
+ mv copy, @file
89
+ @version = @new_version
90
+ end
91
+
92
+ end
93
+ version = Version.new 'lib/reliable-msg.rb', ENV['version']
94
+
95
+
96
+ # Create the GEM package.
97
+ gem_spec = Gem::Specification.new do |spec|
98
+ spec.name = 'reliable-msg'
99
+ spec.version = version.next
100
+ spec.summary = "Reliable messaging and persistent queues for building asynchronous applications in Ruby"
101
+ spec.description = <<-EOF
102
+ This package provides reliable messaging and persistent queues for
103
+ building asynchronous applications in Ruby.
104
+
105
+ It supports transaction processing, message selectors, priorities,
106
+ delivery semantics, remote queue managers, disk-based and MySQL message
107
+ stores and more.
108
+ EOF
109
+ spec.author = "Assaf Arkin"
110
+ spec.email = "assaf@labnotes.org"
111
+ spec.homepage = "http://trac.labnotes.org/cgi-bin/trac.cgi/wiki/RubyReliableMessaging"
112
+
113
+ spec.files = FileList["{bin,test,lib,docs}/**/*", "README", "MIT-LICENSE", "Rakefile"].to_a
114
+ spec.require_path = "lib"
115
+ spec.autorequire = 'reliable-msg.rb'
116
+ spec.bindir = "bin"
117
+ spec.executables = ["queues"]
118
+ spec.default_executable = "queues"
119
+ spec.requirements << "MySQL for database store, otherwise uses the file system"
120
+ spec.has_rdoc = true
121
+ spec.rdoc_options << '--main' << 'README' << '--title' << 'Reliable Messaging for Ruby' << '--line-numbers'
122
+ spec.extra_rdoc_files = ["README"]
123
+ end
124
+
125
+ gem = Rake::GemPackageTask.new(gem_spec) do |pkg|
126
+ pkg.need_tar_gz = true
127
+ pkg.need_zip = true
128
+ end
129
+
130
+
131
+ desc "Look for TODO and FIXME tags in the code"
132
+ task :todo do
133
+ FileList['**/*.rb'].egrep /#.*(FIXME|TODO|TBD)/
134
+ end
135
+
136
+
137
+ # --------------------------------------------------------------------
138
+ # Creating a release
139
+
140
+ desc "Make a new release"
141
+ task :release => [:tests, :prerelease, :clobber, :update_version, :package] do
142
+ puts
143
+ puts "**************************************************************"
144
+ puts "* Release #{version.number} Complete."
145
+ puts "* Packages ready to upload."
146
+ puts "**************************************************************"
147
+ puts
148
+ end
149
+
150
+ task :prerelease do
151
+ if !version.changed? && ENV['reuse'] != version.number
152
+ fail "Current version is #{version.number}, must specify reuse=ver to reuse existing version"
153
+ end
154
+ end
155
+
156
+ task :update_version => [:prerelease] do
157
+ if !version.changed?
158
+ puts "No version change ... skipping version update"
159
+ else
160
+ version.update
161
+ end
162
+ end
163
+
164
+
@@ -0,0 +1,8 @@
1
+ begin
2
+ require 'reliable-msg'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require_gem 'reliable-msg'
6
+ end
7
+ ReliableMsg::CLI.new.run
8
+
@@ -0,0 +1,12 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module ReliableMsg
5
+
6
+ PACKAGE = "reliable-msg"
7
+ VERSION = '1.0.0'
8
+
9
+ end
10
+
11
+ require 'reliable-msg/queue'
12
+ require 'reliable-msg/cli'
@@ -0,0 +1,170 @@
1
+ #
2
+ # = cli.rb - Reliable messaging command-line interface
3
+ #
4
+ # Author:: Assaf Arkin assaf@labnotes.org
5
+ # Documentation:: http://trac.labnotes.org/cgi-bin/trac.cgi/wiki/RubyReliableMessaging
6
+ # Copyright:: Copyright (c) 2005 Assaf Arkin
7
+ # License:: MIT and/or Creative Commons Attribution-ShareAlike
8
+ #
9
+ #--
10
+ # Changes:
11
+ #++
12
+
13
+
14
+ require 'drb'
15
+ require 'optparse'
16
+ require 'rdoc/usage'
17
+ require 'reliable-msg/queue-manager'
18
+
19
+ module ReliableMsg
20
+
21
+ class CLI #:nodoc:
22
+
23
+ USAGE = <<-EOF
24
+ usage: queues [-c config] command [args]
25
+
26
+ To see list of available commands and options
27
+ queues help
28
+ EOF
29
+
30
+ HELP = <<-EOF
31
+ usage: queues [-c config] command [args]
32
+
33
+ Reliable messaging queue manager, version #{VERSION}
34
+
35
+ Available commands:
36
+
37
+ help
38
+ Display this help message.
39
+
40
+ manager start
41
+ Start the queue manager as a standalone server
42
+
43
+ manager stop
44
+ Stop a running queue manager.
45
+
46
+ install disk [<path>]
47
+ Configure queue manager to use disk-based message store
48
+ using the specified directory. Uses 'queues' by default.
49
+
50
+ install mysql <host> <username> <password> <database> [options]
51
+ [--port <port>] [--socket <socket>] [--prefix <prefix>]
52
+ Configure queue manager to use MySQL for message store,
53
+ using the specified connection properties. Updates database
54
+ schema.
55
+
56
+ Options for install mysql are (defaults apply if missing):
57
+
58
+ --port Port to connect to
59
+ --socket Socket to connect to
60
+ --prefix Prefix for table names
61
+
62
+ EOF
63
+
64
+ class InvalidUsage < Exception
65
+ end
66
+
67
+ def initialize
68
+ end
69
+
70
+ def run
71
+ begin
72
+ config_file = nil
73
+ opts = OptionParser.new
74
+ opts.on("-c FILE", "--config FILE", String) { |value| config_file = value }
75
+ opts.on("-v", "--version") do
76
+ puts "Reliable messaging queue manager, version #{VERSION}"
77
+ exit
78
+ end
79
+ opts.on("-h", "--help") do
80
+ puts HELP
81
+ exit
82
+ end
83
+
84
+ args = opts.parse(ARGV)
85
+
86
+ raise InvalidUsage if args.length < 1
87
+ case args[0]
88
+ when 'help'
89
+ puts HELP
90
+
91
+ when 'manager'
92
+ case args[1]
93
+ when 'start', nil
94
+ manager = QueueManager.new({:config=>config_file})
95
+ manager.start
96
+ begin
97
+ while manager.alive?
98
+ sleep 3
99
+ end
100
+ rescue Interrupt
101
+ manager.stop
102
+ end
103
+ when 'stop'
104
+ if config_file
105
+ config = Config.new config_file, nil
106
+ unless config.load_no_create || config_file.nil?
107
+ puts "Could not find configuration file #{config.path}"
108
+ exit
109
+ end
110
+ drb = Config::DEFAULT_DRB
111
+ drb.merge(config.drb) if config.drb
112
+ drb_uri = "druby://localhost:#{drb['port']}"
113
+ else
114
+ drb_uri = Queue::DEFAULT_DRB
115
+ end
116
+ begin
117
+ DRbObject.new(nil, drb_uri).stop
118
+ rescue DRb::DRbConnError =>error
119
+ puts "No queue manager at #{drb_uri}"
120
+ end
121
+ else
122
+ raise InvalidUsage
123
+ end
124
+
125
+ when 'install'
126
+ config = Config.new config_file, nil
127
+ case args[1]
128
+ when 'disk'
129
+ store = MessageStore::Disk.new({}, nil)
130
+ config.store = store.configuration
131
+ if config.create_if_none
132
+ store.setup
133
+ puts "Created queues configuration file: #{config.path}"
134
+ else
135
+ puts "Found existing queues configuration file: #{config.path}"
136
+ puts "No changes made"
137
+ end
138
+ when 'mysql'
139
+ host, username, password, database = args[2], args[3], args[4], args[5]
140
+ raise InvalidUsage unless host && database && username && password
141
+ conn = { "host"=>host, "username"=>username, "password"=>password, "database"=>database }
142
+ store = MessageStore::MySQL.new(conn, nil)
143
+ config.store = store.configuration
144
+ if config.create_if_none
145
+ puts "Created queues configuration file: #{config.path}"
146
+ if store.setup
147
+ puts "Created queue manager tables in database '#{database}'"
148
+ end
149
+ else
150
+ puts "Found existing queues configuration file: #{config.path}"
151
+ puts "No changes made"
152
+ end
153
+ else
154
+ raise InvalidUsage
155
+ end
156
+ else
157
+ raise InvalidUsage
158
+ end
159
+ rescue InvalidUsage
160
+ puts USAGE
161
+ end
162
+ end
163
+
164
+ end
165
+
166
+ end
167
+
168
+ if __FILE__ == $0
169
+ ReliableMsg::CLI.new.run
170
+ end