homeq 1.1.4
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 +103 -0
- data/COPYING +348 -0
- data/README.rdoc +64 -0
- data/Rakefile +131 -0
- data/bin/hq +6 -0
- data/config/boot.rb +224 -0
- data/config/databases/frontbase.yml +28 -0
- data/config/databases/mysql.yml +54 -0
- data/config/databases/oracle.yml +39 -0
- data/config/databases/postgresql.yml +48 -0
- data/config/databases/sqlite2.yml +16 -0
- data/config/databases/sqlite3.yml +19 -0
- data/config/environment.rb +20 -0
- data/config/environments/development.cfg +35 -0
- data/config/environments/production.cfg +35 -0
- data/config/environments/test.cfg +35 -0
- data/config/generators/job/templates/job.rb.erb +20 -0
- data/config/generators/message/templates/messages/MESSAGE.proto.erb +12 -0
- data/config/generators/model/templates/models/MODEL.rb.erb +3 -0
- data/config/generators/service/templates/services/SERVICE.rb.erb +43 -0
- data/config/homeq.cfg +35 -0
- data/extras/consumer.rb +85 -0
- data/extras/homeq.cfg +49 -0
- data/extras/hqd.rb +33 -0
- data/extras/producer.rb +79 -0
- data/extras/simple_consumer.rb +53 -0
- data/lib/homeq/base/base.rb +44 -0
- data/lib/homeq/base/commando.rb +81 -0
- data/lib/homeq/base/config.rb +99 -0
- data/lib/homeq/base/exception.rb +48 -0
- data/lib/homeq/base/histogram.rb +141 -0
- data/lib/homeq/base/logger.rb +185 -0
- data/lib/homeq/base/ohash.rb +297 -0
- data/lib/homeq/base/options.rb +171 -0
- data/lib/homeq/base/poolable.rb +100 -0
- data/lib/homeq/base/system.rb +446 -0
- data/lib/homeq/cli.rb +35 -0
- data/lib/homeq/cp/commands.rb +71 -0
- data/lib/homeq/cp/connection.rb +97 -0
- data/lib/homeq/cp/cp.rb +30 -0
- data/lib/homeq/cp/server.rb +105 -0
- data/lib/homeq/sobs/client.rb +119 -0
- data/lib/homeq/sobs/connection.rb +635 -0
- data/lib/homeq/sobs/foreman.rb +237 -0
- data/lib/homeq/sobs/job.rb +66 -0
- data/lib/homeq/sobs/message.rb +49 -0
- data/lib/homeq/sobs/queue.rb +224 -0
- data/lib/homeq/sobs/sender.rb +150 -0
- data/lib/homeq/sobs/server.rb +654 -0
- data/lib/homeq/sobs/sobs.rb +45 -0
- data/lib/homeq/sobs/topology.rb +111 -0
- data/lib/homeq.rb +106 -0
- data/lib/tasks/Rakefile +49 -0
- data/lib/tasks/database.rake +387 -0
- data/lib/tasks/gem.rake +9 -0
- data/lib/tasks/generate.rake +192 -0
- data/lib/tasks/hq.rake +171 -0
- data/lib/tasks/testing.rake +95 -0
- data/lib/tasks/utility.rb +17 -0
- data/script/console.rb +45 -0
- data/script/generate +7 -0
- data/test/unittest.rb +51 -0
- metadata +222 -0
data/config/boot.rb
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
#############################################################################
|
2
|
+
#
|
3
|
+
# Author:: Colin Steele (colin@colinsteele.org)
|
4
|
+
# Homepage::
|
5
|
+
#
|
6
|
+
#----------------------------------------------------------------------------
|
7
|
+
#
|
8
|
+
# Copyright (C) 2008 by Colin Steele. All Rights Reserved.
|
9
|
+
# colin@colinsteele.org
|
10
|
+
#
|
11
|
+
# This program is free software; you can redistribute it and/or modify
|
12
|
+
# it under the terms of either: 1) the GNU General Public License
|
13
|
+
# as published by the Free Software Foundation; either version 2 of the
|
14
|
+
# License, or (at your option) any later version; or 2) Ruby's License.
|
15
|
+
#
|
16
|
+
# See the file COPYING for complete licensing information.
|
17
|
+
#
|
18
|
+
#---------------------------------------------------------------------------
|
19
|
+
#
|
20
|
+
#
|
21
|
+
#############################################################################
|
22
|
+
|
23
|
+
unless defined?(HOMEQ_APP_ROOT)
|
24
|
+
HOMEQ_APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
25
|
+
end
|
26
|
+
|
27
|
+
module HomeQ
|
28
|
+
class << self
|
29
|
+
def boot!
|
30
|
+
unless booted?
|
31
|
+
pick_boot.init
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def booted?
|
36
|
+
defined? HOMEQ_ROOT
|
37
|
+
end
|
38
|
+
|
39
|
+
def pick_boot
|
40
|
+
(vendor_homeq? ? VendorBoot : GemBoot).new
|
41
|
+
end
|
42
|
+
|
43
|
+
def vendor_homeq?
|
44
|
+
File.exist?("#{HOMEQ_APP_ROOT}/vendor/homeq")
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class Boot
|
50
|
+
|
51
|
+
@config = nil
|
52
|
+
|
53
|
+
class << self
|
54
|
+
attr :config, true
|
55
|
+
end
|
56
|
+
|
57
|
+
attr :config, true
|
58
|
+
|
59
|
+
def set_gem_path
|
60
|
+
path = File.expand_path("#{File.dirname(__FILE__)}/../vendor/gems")
|
61
|
+
Gem.clear_paths
|
62
|
+
gem_paths = [path, Gem.default_dir]
|
63
|
+
gem_paths << APPLE_GEM_HOME if defined?(APPLE_GEM_HOME)
|
64
|
+
Gem.send :set_paths, gem_paths.join(":")
|
65
|
+
end
|
66
|
+
|
67
|
+
def set_load_paths
|
68
|
+
paths = %w(
|
69
|
+
app
|
70
|
+
app/services
|
71
|
+
app/models
|
72
|
+
app/messages
|
73
|
+
app/messages/wire
|
74
|
+
lib
|
75
|
+
vendor
|
76
|
+
).map { |d| File.join(HOMEQ_APP_ROOT, d) }
|
77
|
+
paths += @config['load_paths']
|
78
|
+
paths.reverse_each { |dir|
|
79
|
+
$LOAD_PATH.unshift(dir) if File.directory?(dir)
|
80
|
+
}
|
81
|
+
$LOAD_PATH.uniq!
|
82
|
+
ActiveSupport::Dependencies.load_paths = paths
|
83
|
+
end
|
84
|
+
def self.database_configuration
|
85
|
+
require 'erb'
|
86
|
+
YAML::load(ERB.new(IO.read(database_configuration_file)).result)
|
87
|
+
end
|
88
|
+
def self.database_configuration_file
|
89
|
+
File.join(HOMEQ_APP_ROOT, 'config', 'database.yml')
|
90
|
+
end
|
91
|
+
def self.database_configuration_parameters(environment = nil)
|
92
|
+
env = (environment || HOMEQ_ENV).to_s
|
93
|
+
params = @config['database_configuration'][env]
|
94
|
+
params = HashWithIndifferentAccess.new(params)
|
95
|
+
params[:user] ||= params[:username]
|
96
|
+
params
|
97
|
+
end
|
98
|
+
def self.establish_database_connection(environment = nil)
|
99
|
+
params =
|
100
|
+
database_configuration_parameters(environment || HOMEQ_ENV)
|
101
|
+
@config['sequel_database_connection'] = Sequel.connect(params)
|
102
|
+
silence_warnings do
|
103
|
+
HomeQ.const_set(:DB, self.config['sequel_database_connection'])
|
104
|
+
end
|
105
|
+
if defined?(EventedMysql)
|
106
|
+
params[:connections] ||= 4
|
107
|
+
# uncomment to see sequel logging
|
108
|
+
# params[:logging] = true
|
109
|
+
params.each { |k,v|
|
110
|
+
if k.is_a?(Symbol)
|
111
|
+
EventedMysql.settings[k] = v
|
112
|
+
else
|
113
|
+
EventedMysql.settings[k.intern] = v
|
114
|
+
end
|
115
|
+
}
|
116
|
+
end
|
117
|
+
HomeQ::DB
|
118
|
+
end
|
119
|
+
def init
|
120
|
+
Boot.load_rubygems
|
121
|
+
set_gem_path
|
122
|
+
load_homeq
|
123
|
+
end
|
124
|
+
def self.run
|
125
|
+
b = self.new
|
126
|
+
b.config = default_config
|
127
|
+
yield b.config if block_given?
|
128
|
+
b.load_gems
|
129
|
+
b.require_dependencies
|
130
|
+
b.set_load_paths
|
131
|
+
HomeQ::Boot.establish_database_connection
|
132
|
+
end
|
133
|
+
def require_dependencies
|
134
|
+
require 'eventmachine'
|
135
|
+
require 'statemachine'
|
136
|
+
require 'activesupport'
|
137
|
+
require 'sequel'
|
138
|
+
require_homeq_dependencies
|
139
|
+
end
|
140
|
+
def require_homeq_dependencies
|
141
|
+
require 'homeq/base/base'
|
142
|
+
require 'homeq/cp/cp'
|
143
|
+
require 'homeq/sobs/sobs'
|
144
|
+
end
|
145
|
+
def load_gems
|
146
|
+
self.config.gems.each { |name, opts|
|
147
|
+
if opts[:version]
|
148
|
+
gem(name, opts[:version])
|
149
|
+
else
|
150
|
+
gem(name)
|
151
|
+
end
|
152
|
+
require(opts[:lib] || name)
|
153
|
+
}
|
154
|
+
end
|
155
|
+
def self.default_config
|
156
|
+
require 'homeq/base/base'
|
157
|
+
self.config ||= HomeQ::Base::Configuration::Configuration.instance
|
158
|
+
self.config['database_configuration'] = database_configuration
|
159
|
+
self.config
|
160
|
+
end
|
161
|
+
def self.rubygems_version
|
162
|
+
Gem::RubyGemsVersion if defined? Gem::RubyGemsVersion
|
163
|
+
end
|
164
|
+
def self.gem_version
|
165
|
+
if defined? HOMEQ_GEM_VERSION
|
166
|
+
HOMEQ_GEM_VERSION
|
167
|
+
elsif ENV.include?('HOMEQ_GEM_VERSION')
|
168
|
+
ENV['HOMEQ_GEM_VERSION']
|
169
|
+
else
|
170
|
+
parse_gem_version(read_environment_rb)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
def self.parse_gem_version(text)
|
174
|
+
$1 if text =~ /^[^#]*HOMEQ_GEM_VERSION\s*=\s*'([!~<>=]*\s*[\d.]+)'/
|
175
|
+
end
|
176
|
+
private
|
177
|
+
def self.read_environment_rb
|
178
|
+
File.read(File.expand_path("#{File.dirname(__FILE__)}/../config/environment.rb"))
|
179
|
+
end
|
180
|
+
def self.load_rubygems
|
181
|
+
require 'rubygems'
|
182
|
+
|
183
|
+
unless rubygems_version >= '0.9.4'
|
184
|
+
$stderr.puts %(Homeq requires RubyGems >= 0.9.4 (you have #{rubygems_version}). Please `gem update --system` and try again.)
|
185
|
+
exit 1
|
186
|
+
end
|
187
|
+
|
188
|
+
rescue LoadError
|
189
|
+
$stderr.puts %(Homeq requires RubyGems >= 0.9.4. Please install RubyGems and try again: http://rubygems.rubyforge.org)
|
190
|
+
exit 1
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
class VendorBoot < Boot
|
195
|
+
def load_homeq
|
196
|
+
path = File.expand_path("#{File.dirname(__FILE__)}/../vendor/homeq/lib/homeq")
|
197
|
+
require path
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
class GemBoot < Boot
|
202
|
+
def load_homeq
|
203
|
+
load_homeq_gem
|
204
|
+
end
|
205
|
+
|
206
|
+
def load_homeq_gem
|
207
|
+
if version = self.class.gem_version
|
208
|
+
gem 'homeq', version
|
209
|
+
else
|
210
|
+
gem 'homeq'
|
211
|
+
end
|
212
|
+
require 'homeq'
|
213
|
+
rescue Gem::LoadError => load_error
|
214
|
+
$stderr.puts %(#{load_error})
|
215
|
+
$stderr.puts %(Missing the HomeQ #{version} gem or a prerequisite?)
|
216
|
+
$stderr.puts %(program requires version #{version} of homeq)
|
217
|
+
exit 1
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# All that for this:
|
224
|
+
HomeQ.boot!
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# FrontBase versions 4.x
|
2
|
+
#
|
3
|
+
# Get the bindings:
|
4
|
+
# gem install ruby-frontbase
|
5
|
+
|
6
|
+
development:
|
7
|
+
adapter: frontbase
|
8
|
+
host: localhost
|
9
|
+
database: <%= app_name %>_development
|
10
|
+
username: <%= app_name %>
|
11
|
+
password: ''
|
12
|
+
|
13
|
+
# Warning: The database defined as "test" will be erased and
|
14
|
+
# re-generated from your development database when you run "rake".
|
15
|
+
# Do not set this db to the same as development or production.
|
16
|
+
test:
|
17
|
+
adapter: frontbase
|
18
|
+
host: localhost
|
19
|
+
database: <%= app_name %>_test
|
20
|
+
username: <%= app_name %>
|
21
|
+
password: ''
|
22
|
+
|
23
|
+
production:
|
24
|
+
adapter: frontbase
|
25
|
+
host: localhost
|
26
|
+
database: <%= app_name %>_production
|
27
|
+
username: <%= app_name %>
|
28
|
+
password: ''
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# MySQL. Versions 4.1 and 5.0 are recommended.
|
2
|
+
#
|
3
|
+
# Install the MySQL driver:
|
4
|
+
# gem install mysql
|
5
|
+
# On Mac OS X:
|
6
|
+
# sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
|
7
|
+
# On Mac OS X Leopard:
|
8
|
+
# sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
|
9
|
+
# This sets the ARCHFLAGS environment variable to your native architecture
|
10
|
+
# On Windows:
|
11
|
+
# gem install mysql
|
12
|
+
# Choose the win32 build.
|
13
|
+
# Install MySQL and put its /bin directory on your path.
|
14
|
+
#
|
15
|
+
# And be sure to use new-style password hashing:
|
16
|
+
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
|
17
|
+
development:
|
18
|
+
adapter: mysql
|
19
|
+
encoding: utf8
|
20
|
+
database: <%= app_name %>_development
|
21
|
+
username: root
|
22
|
+
password:
|
23
|
+
<% if socket -%>
|
24
|
+
socket: <%= socket %>
|
25
|
+
<% else -%>
|
26
|
+
host: localhost
|
27
|
+
<% end -%>
|
28
|
+
|
29
|
+
# Warning: The database defined as "test" will be erased and
|
30
|
+
# re-generated from your development database when you run "rake".
|
31
|
+
# Do not set this db to the same as development or production.
|
32
|
+
test:
|
33
|
+
adapter: mysql
|
34
|
+
encoding: utf8
|
35
|
+
database: <%= app_name %>_test
|
36
|
+
username: root
|
37
|
+
password:
|
38
|
+
<% if socket -%>
|
39
|
+
socket: <%= socket %>
|
40
|
+
<% else -%>
|
41
|
+
host: localhost
|
42
|
+
<% end -%>
|
43
|
+
|
44
|
+
production:
|
45
|
+
adapter: mysql
|
46
|
+
encoding: utf8
|
47
|
+
database: <%= app_name %>_production
|
48
|
+
username: root
|
49
|
+
password:
|
50
|
+
<% if socket -%>
|
51
|
+
socket: <%= socket %>
|
52
|
+
<% else -%>
|
53
|
+
host: localhost
|
54
|
+
<% end -%>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Oracle/OCI 8i, 9, 10g
|
2
|
+
#
|
3
|
+
# Requires Ruby/OCI8:
|
4
|
+
# http://rubyforge.org/projects/ruby-oci8/
|
5
|
+
#
|
6
|
+
# Specify your database using any valid connection syntax, such as a
|
7
|
+
# tnsnames.ora service name, or a SQL connect url string of the form:
|
8
|
+
#
|
9
|
+
# //host:[port][/service name]
|
10
|
+
#
|
11
|
+
# By default prefetch_rows (OCI_ATTR_PREFETCH_ROWS) is set to 100. And
|
12
|
+
# until true bind variables are supported, cursor_sharing is set by default
|
13
|
+
# to 'similar'. Both can be changed in the configation below; the defaults
|
14
|
+
# are equivalent to specifying:
|
15
|
+
#
|
16
|
+
# prefetch_rows: 100
|
17
|
+
# cursor_sharing: similar
|
18
|
+
#
|
19
|
+
|
20
|
+
development:
|
21
|
+
adapter: oracle
|
22
|
+
database: <%= app_name %>_development
|
23
|
+
username: <%= app_name %>
|
24
|
+
password:
|
25
|
+
|
26
|
+
# Warning: The database defined as "test" will be erased and
|
27
|
+
# re-generated from your development database when you run "rake".
|
28
|
+
# Do not set this db to the same as development or production.
|
29
|
+
test:
|
30
|
+
adapter: oracle
|
31
|
+
database: <%= app_name %>_test
|
32
|
+
username: <%= app_name %>
|
33
|
+
password:
|
34
|
+
|
35
|
+
production:
|
36
|
+
adapter: oracle
|
37
|
+
database: <%= app_name %>_production
|
38
|
+
username: <%= app_name %>
|
39
|
+
password:
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# PostgreSQL. Versions 7.4 and 8.x are supported.
|
2
|
+
#
|
3
|
+
# Install the ruby-postgres driver:
|
4
|
+
# gem install ruby-postgres
|
5
|
+
# On Mac OS X:
|
6
|
+
# gem install ruby-postgres -- --include=/usr/local/pgsql
|
7
|
+
# On Windows:
|
8
|
+
# gem install ruby-postgres
|
9
|
+
# Choose the win32 build.
|
10
|
+
# Install PostgreSQL and put its /bin directory on your path.
|
11
|
+
development:
|
12
|
+
adapter: postgresql
|
13
|
+
encoding: unicode
|
14
|
+
database: <%= app_name %>_development
|
15
|
+
username: <%= app_name %>
|
16
|
+
password:
|
17
|
+
|
18
|
+
# Connect on a TCP socket. Omitted by default since the client uses a
|
19
|
+
# domain socket that doesn't need configuration. Windows does not have
|
20
|
+
# domain sockets, so uncomment these lines.
|
21
|
+
#host: localhost
|
22
|
+
#port: 5432
|
23
|
+
|
24
|
+
# Schema search path. The server defaults to $user,public
|
25
|
+
#schema_search_path: myapp,sharedapp,public
|
26
|
+
|
27
|
+
# Minimum log levels, in increasing order:
|
28
|
+
# debug5, debug4, debug3, debug2, debug1,
|
29
|
+
# log, notice, warning, error, fatal, and panic
|
30
|
+
# The server defaults to notice.
|
31
|
+
#min_messages: warning
|
32
|
+
|
33
|
+
# Warning: The database defined as "test" will be erased and
|
34
|
+
# re-generated from your development database when you run "rake".
|
35
|
+
# Do not set this db to the same as development or production.
|
36
|
+
test:
|
37
|
+
adapter: postgresql
|
38
|
+
encoding: unicode
|
39
|
+
database: <%= app_name %>_test
|
40
|
+
username: <%= app_name %>
|
41
|
+
password:
|
42
|
+
|
43
|
+
production:
|
44
|
+
adapter: postgresql
|
45
|
+
encoding: unicode
|
46
|
+
database: <%= app_name %>_production
|
47
|
+
username: <%= app_name %>
|
48
|
+
password:
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# SQLite version 2.x
|
2
|
+
# gem install sqlite-ruby
|
3
|
+
development:
|
4
|
+
adapter: sqlite
|
5
|
+
database: db/development.sqlite2
|
6
|
+
|
7
|
+
# Warning: The database defined as "test" will be erased and
|
8
|
+
# re-generated from your development database when you run "rake".
|
9
|
+
# Do not set this db to the same as development or production.
|
10
|
+
test:
|
11
|
+
adapter: sqlite
|
12
|
+
database: db/test.sqlite2
|
13
|
+
|
14
|
+
production:
|
15
|
+
adapter: sqlite
|
16
|
+
database: db/production.sqlite2
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# SQLite version 3.x
|
2
|
+
# gem install sqlite3-ruby (not necessary on OS X Leopard)
|
3
|
+
development:
|
4
|
+
adapter: sqlite3
|
5
|
+
database: db/development.sqlite3
|
6
|
+
timeout: 5000
|
7
|
+
|
8
|
+
# Warning: The database defined as "test" will be erased and
|
9
|
+
# re-generated from your development database when you run "rake".
|
10
|
+
# Do not set this db to the same as development or production.
|
11
|
+
test:
|
12
|
+
adapter: sqlite3
|
13
|
+
database: db/test.sqlite3
|
14
|
+
timeout: 5000
|
15
|
+
|
16
|
+
production:
|
17
|
+
adapter: sqlite3
|
18
|
+
database: db/production.sqlite3
|
19
|
+
timeout: 5000
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Uncomment below to force HomeQ into production mode
|
2
|
+
# ENV['HOMEQ_ENV'] ||= 'production'
|
3
|
+
|
4
|
+
# Uncomment below to force a gem load path
|
5
|
+
# ENV['GEM_PATH'] = '/some/place:/some/other/place'
|
6
|
+
|
7
|
+
# Specifies gem version of HomeQ to use when vendor/homeq is not present
|
8
|
+
HOMEQ_GEM_VERSION = '1.1.3' unless defined? HOMEQ_GEM_VERSION
|
9
|
+
|
10
|
+
# Bootstrap the Homeq framework
|
11
|
+
require File.join(File.dirname(__FILE__), 'boot')
|
12
|
+
|
13
|
+
HomeQ::Boot.run { |config|
|
14
|
+
|
15
|
+
# Put your intialization configuration here
|
16
|
+
|
17
|
+
# Configure gem versions here
|
18
|
+
# config.gem "foo", :version => '=1.1.1'
|
19
|
+
|
20
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
###### CONTROL PORTS ######
|
2
|
+
|
3
|
+
# In dev, all of this runs on localhost, so we need different control
|
4
|
+
# ports
|
5
|
+
|
6
|
+
raise "No queue name set; -q on command line, or in config file" if !queue_name
|
7
|
+
ports = {}
|
8
|
+
QUEUES.each_with_index { |name, i|
|
9
|
+
ports[name] = CP_BASE_PORT + i
|
10
|
+
}
|
11
|
+
cp_port ports[queue_name]
|
12
|
+
|
13
|
+
###### QUEUE CONNECTION GRAPH ######
|
14
|
+
|
15
|
+
topology {
|
16
|
+
|
17
|
+
# Homes - this tells us where a given queue's process runs (a la
|
18
|
+
# hostname), and which host/port it listens on for connections.
|
19
|
+
|
20
|
+
hostname = `hostname`.chomp
|
21
|
+
QUEUES.each_with_index { |name, i|
|
22
|
+
queue(name) { |q|
|
23
|
+
q.located_at('localhost', QUEUE_BASE_PORT + i, hostname)
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
# Connections
|
28
|
+
|
29
|
+
queue('producer') {
|
30
|
+
writes_to('holder')
|
31
|
+
}
|
32
|
+
queue('consumer') {
|
33
|
+
reads_from('holder')
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
###### CONTROL PORTS ######
|
2
|
+
|
3
|
+
# In dev, all of this runs on localhost, so we need different control
|
4
|
+
# ports
|
5
|
+
|
6
|
+
raise "No queue name set; -q on command line, or in config file" if !queue_name
|
7
|
+
ports = {}
|
8
|
+
QUEUES.each_with_index { |name, i|
|
9
|
+
ports[name] = CP_BASE_PORT + i
|
10
|
+
}
|
11
|
+
cp_port ports[queue_name]
|
12
|
+
|
13
|
+
###### QUEUE CONNECTION GRAPH ######
|
14
|
+
|
15
|
+
topology {
|
16
|
+
|
17
|
+
# Homes - this tells us where a given queue's process runs (a la
|
18
|
+
# hostname), and which host/port it listens on for connections.
|
19
|
+
|
20
|
+
hostname = `hostname`.chomp
|
21
|
+
QUEUES.each_with_index { |name, i|
|
22
|
+
queue(name) { |q|
|
23
|
+
q.located_at('localhost', QUEUE_BASE_PORT + i, hostname)
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
# Connections
|
28
|
+
|
29
|
+
queue('producer') {
|
30
|
+
writes_to('holder')
|
31
|
+
}
|
32
|
+
queue('consumer') {
|
33
|
+
reads_from('holder')
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
###### CONTROL PORTS ######
|
2
|
+
|
3
|
+
# In dev, all of this runs on localhost, so we need different control
|
4
|
+
# ports
|
5
|
+
|
6
|
+
raise "No queue name set; -q on command line, or in config file" if !queue_name
|
7
|
+
ports = {}
|
8
|
+
QUEUES.each_with_index { |name, i|
|
9
|
+
ports[name] = CP_BASE_PORT + i
|
10
|
+
}
|
11
|
+
cp_port ports[queue_name]
|
12
|
+
|
13
|
+
###### QUEUE CONNECTION GRAPH ######
|
14
|
+
|
15
|
+
topology {
|
16
|
+
|
17
|
+
# Homes - this tells us where a given queue's process runs (a la
|
18
|
+
# hostname), and which host/port it listens on for connections.
|
19
|
+
|
20
|
+
hostname = `hostname`.chomp
|
21
|
+
QUEUES.each_with_index { |name, i|
|
22
|
+
queue(name) { |q|
|
23
|
+
q.located_at('localhost', QUEUE_BASE_PORT + i, hostname)
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
# Connections
|
28
|
+
|
29
|
+
queue('producer') {
|
30
|
+
writes_to('holder')
|
31
|
+
}
|
32
|
+
queue('consumer') {
|
33
|
+
reads_from('holder')
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module <%= service_name.camelize %>Service
|
4
|
+
class Job < HomeQ::SOBS::Job
|
5
|
+
include HomeQ
|
6
|
+
@jobs = 0
|
7
|
+
class << self
|
8
|
+
attr :jobs, true
|
9
|
+
end
|
10
|
+
def initialize(message, queue)
|
11
|
+
super(message, queue)
|
12
|
+
Job.jobs += 1
|
13
|
+
end
|
14
|
+
def run
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
package wire;
|
2
|
+
|
3
|
+
message <%= message_name.camelize %> {
|
4
|
+
<%- if task.args -%>
|
5
|
+
<%- task.args[1..-1].each_with_index do |tuple,i| %>
|
6
|
+
<%- tuple = tuple.split(':') %>
|
7
|
+
<%- required = ((tuple[2] || '') =~ /yes|true|required|on/i) %>
|
8
|
+
<%= required ? 'required' : 'optional' %> <%= tuple[1] %> <%= tuple[0] %> = <%= i + 1 %>;
|
9
|
+
<% end %>
|
10
|
+
<%- end -%>
|
11
|
+
}
|
12
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
##############################################################################
|
4
|
+
#
|
5
|
+
# <%= service_name %>
|
6
|
+
#
|
7
|
+
##############################################################################
|
8
|
+
|
9
|
+
require File.join(File.dirname(__FILE__), '../../config/environment')
|
10
|
+
|
11
|
+
# Gives us easy access to log, system and config.
|
12
|
+
include HomeQ
|
13
|
+
|
14
|
+
#############################################################################
|
15
|
+
# Command line options
|
16
|
+
#############################################################################
|
17
|
+
|
18
|
+
parser = HomeQ::Base::Options::Options.instance.parser
|
19
|
+
options = HomeQ::Base::Options::Options.instance.options
|
20
|
+
|
21
|
+
# Service specific options setup goes here
|
22
|
+
##
|
23
|
+
## parser.separator ""
|
24
|
+
## parser.separator "<%= service_name %> specific options:"
|
25
|
+
##
|
26
|
+
## options.<%= service_name %>_frob = 'localhost'
|
27
|
+
## parser.on("--<%= service_name %>-frob FOO",
|
28
|
+
## "frobnitz; defaults to #{options.<%= service_name %>_frob}") { |o|
|
29
|
+
## options.<%= service_name %>_frob = o
|
30
|
+
## }
|
31
|
+
|
32
|
+
#############################################################################
|
33
|
+
# Prep for and run HQ
|
34
|
+
#############################################################################
|
35
|
+
|
36
|
+
sys.start {
|
37
|
+
# Install our handler for jobs we get on our home queue
|
38
|
+
sys.handlers[config.queue_name] = <%= service_name.camelize %>Service::Job
|
39
|
+
logger.info {
|
40
|
+
"Queue #{config.queue_name} handled by #{<%= service_name.camelize %>Service::Job}"
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
data/config/homeq.cfg
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
###### BASIC CONFIGURATION ######
|
2
|
+
|
3
|
+
QUEUES = %w(holder producer consumer)
|
4
|
+
queue_retry 10 # client queue connections retried after this long
|
5
|
+
|
6
|
+
###### LOGGING ######
|
7
|
+
|
8
|
+
# I think this makes things more readable.
|
9
|
+
|
10
|
+
log_id queue_name
|
11
|
+
|
12
|
+
# Uncomment the next line to send logging to syslog
|
13
|
+
#
|
14
|
+
# syslog
|
15
|
+
|
16
|
+
# Uncomment the next line to change the log level, which is also
|
17
|
+
# overidden using command line -vvv
|
18
|
+
#
|
19
|
+
# Levels are: DEBUG4 DEBUG3 DEBUG2 DEBUG1 DEBUG INFO WARN ERROR FATAL
|
20
|
+
#
|
21
|
+
# log_level "DEBUG"
|
22
|
+
|
23
|
+
# Now go and read HOMEQ_ENV-specific configuration. Usually an
|
24
|
+
# env-specific config file will have a queue topology suited to the
|
25
|
+
# host(s) it runs on. Eg., a development topology will have queues
|
26
|
+
# all running on the same machine.
|
27
|
+
|
28
|
+
CP_BASE_PORT = 26000
|
29
|
+
QUEUE_BASE_PORT = 25000
|
30
|
+
|
31
|
+
conf_dir = File.join(HOMEQ_APP_ROOT, 'config')
|
32
|
+
config.read_config_file(File.join(conf_dir,
|
33
|
+
'environments',
|
34
|
+
"#{HOMEQ_ENV}.cfg"))
|
35
|
+
|