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.
Files changed (63) hide show
  1. data/CHANGELOG +103 -0
  2. data/COPYING +348 -0
  3. data/README.rdoc +64 -0
  4. data/Rakefile +131 -0
  5. data/bin/hq +6 -0
  6. data/config/boot.rb +224 -0
  7. data/config/databases/frontbase.yml +28 -0
  8. data/config/databases/mysql.yml +54 -0
  9. data/config/databases/oracle.yml +39 -0
  10. data/config/databases/postgresql.yml +48 -0
  11. data/config/databases/sqlite2.yml +16 -0
  12. data/config/databases/sqlite3.yml +19 -0
  13. data/config/environment.rb +20 -0
  14. data/config/environments/development.cfg +35 -0
  15. data/config/environments/production.cfg +35 -0
  16. data/config/environments/test.cfg +35 -0
  17. data/config/generators/job/templates/job.rb.erb +20 -0
  18. data/config/generators/message/templates/messages/MESSAGE.proto.erb +12 -0
  19. data/config/generators/model/templates/models/MODEL.rb.erb +3 -0
  20. data/config/generators/service/templates/services/SERVICE.rb.erb +43 -0
  21. data/config/homeq.cfg +35 -0
  22. data/extras/consumer.rb +85 -0
  23. data/extras/homeq.cfg +49 -0
  24. data/extras/hqd.rb +33 -0
  25. data/extras/producer.rb +79 -0
  26. data/extras/simple_consumer.rb +53 -0
  27. data/lib/homeq/base/base.rb +44 -0
  28. data/lib/homeq/base/commando.rb +81 -0
  29. data/lib/homeq/base/config.rb +99 -0
  30. data/lib/homeq/base/exception.rb +48 -0
  31. data/lib/homeq/base/histogram.rb +141 -0
  32. data/lib/homeq/base/logger.rb +185 -0
  33. data/lib/homeq/base/ohash.rb +297 -0
  34. data/lib/homeq/base/options.rb +171 -0
  35. data/lib/homeq/base/poolable.rb +100 -0
  36. data/lib/homeq/base/system.rb +446 -0
  37. data/lib/homeq/cli.rb +35 -0
  38. data/lib/homeq/cp/commands.rb +71 -0
  39. data/lib/homeq/cp/connection.rb +97 -0
  40. data/lib/homeq/cp/cp.rb +30 -0
  41. data/lib/homeq/cp/server.rb +105 -0
  42. data/lib/homeq/sobs/client.rb +119 -0
  43. data/lib/homeq/sobs/connection.rb +635 -0
  44. data/lib/homeq/sobs/foreman.rb +237 -0
  45. data/lib/homeq/sobs/job.rb +66 -0
  46. data/lib/homeq/sobs/message.rb +49 -0
  47. data/lib/homeq/sobs/queue.rb +224 -0
  48. data/lib/homeq/sobs/sender.rb +150 -0
  49. data/lib/homeq/sobs/server.rb +654 -0
  50. data/lib/homeq/sobs/sobs.rb +45 -0
  51. data/lib/homeq/sobs/topology.rb +111 -0
  52. data/lib/homeq.rb +106 -0
  53. data/lib/tasks/Rakefile +49 -0
  54. data/lib/tasks/database.rake +387 -0
  55. data/lib/tasks/gem.rake +9 -0
  56. data/lib/tasks/generate.rake +192 -0
  57. data/lib/tasks/hq.rake +171 -0
  58. data/lib/tasks/testing.rake +95 -0
  59. data/lib/tasks/utility.rb +17 -0
  60. data/script/console.rb +45 -0
  61. data/script/generate +7 -0
  62. data/test/unittest.rb +51 -0
  63. metadata +222 -0
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/ruby
2
+
3
+ #############################################################################
4
+ #
5
+ # $Id: homeq.rb 8 2008-08-27 20:15:22Z colin $
6
+ #
7
+ # This code is distributed freely in the sense of GNU GPL.
8
+ # K.Kodama 2005-03-01
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2008 by Colin Steele. All Rights Reserved.
13
+ # colin@colinsteele.org
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+ #############################################################################
26
+
27
+ module HomeQ
28
+
29
+ class Histogram
30
+ attr :min;
31
+ attr :max;
32
+ attr :w; # class width
33
+ attr :f; # array of frequency
34
+
35
+ attr :num;
36
+ attr :s1;
37
+ attr :s2;
38
+ attr :s3;
39
+ attr :s4;
40
+
41
+ def h_class(x)
42
+ ((x-@min)/@w).truncate
43
+ end;
44
+ def bar(x,unit=1)
45
+ n = (x.to_f.nan? ? 0 : x.to_f / unit).ceil
46
+ ("----+" * (n/5+1))[0,n]
47
+ end;
48
+
49
+ def initialize(min,max,width)
50
+ @min=min; @max=max; @w=width; @f=Array::new(h_class(@max)+1,0)
51
+ @num=0; @s1=0.0; @s2=0.0; @s3=0.0; @s4=0.0;
52
+ end
53
+
54
+ def push(x)
55
+ @num+=1; @s1+=x; @s2+=(x**2); @s3+=(x**3); @s4+=(x**4);
56
+ @f[h_class([[@min,x].max, @max].min)]+=1
57
+ end
58
+ alias_method :<<, :push
59
+
60
+ # statistics
61
+ def size
62
+ @num # s=0; @f.each{|n| s+=n}; return s
63
+ end
64
+
65
+ def sum
66
+ @s1
67
+ end
68
+
69
+ def avg
70
+ @s1/@num # average or arithmetic mean
71
+ end
72
+
73
+ def variance
74
+ (@s2/@num)-(@s1/@num)**2 # v=E((x-m)^2)=E(x^2)-m^2 where m=E(X).
75
+ end
76
+
77
+ def sd
78
+ return 0 if variance.nan?
79
+ Math::sqrt(variance) # standard deviation.
80
+ end
81
+
82
+ def cv
83
+ sd/avg # coefficient of variation
84
+ end
85
+
86
+ def skewness
87
+ # skewness E((x-m)^3)/s^3=(E(x^3)-3*m*E(x^2) + 2 m ^3)/s^3
88
+ m=avg; s=sd; ((@s3-3*m*@s2)/@num+2*m*m*m)/(s*s*s)
89
+ end
90
+
91
+ def kurtosis
92
+ # kurtosis E((x-m)^4)/s^4=(E(x^4)-4mE(x^3)+6m^2E(x^2)-3m^4)/s^4
93
+ m=avg; v=variance; ((@s4-4*m*@s3+6*m*m*@s2)/@num-3*m**4)/(v*v)
94
+ end
95
+
96
+ def to_s(unit=1)
97
+ form=sprintf("%%%d.1f-.:%%s %%2.1f%%%% %%d\n", @max.to_s.size + 2)
98
+ s = ''
99
+ for i in 0..h_class(@max)
100
+ percentage = @f[i].to_f / size * 100.0
101
+ s << sprintf(form,
102
+ @min+i*@w,
103
+ bar(percentage / 1.8, unit),
104
+ percentage.nan? ? 0 : percentage,
105
+ @f[i])
106
+ end
107
+ s
108
+ end
109
+
110
+ def report(unit=1)
111
+ str = to_s(unit)
112
+ str <<
113
+ "number: %d, average: %4.2f, std dev: %4.2f\n" % [size, avg, sd]
114
+ end
115
+
116
+ end # Histogram
117
+
118
+ end # HomeQ
119
+
120
+ if $0 == __FILE__
121
+
122
+ require 'test/unit/testsuite'
123
+ require 'test/unit'
124
+
125
+ class TC_MyTest < Test::Unit::TestCase
126
+ def test_simple
127
+
128
+ # Example.
129
+ hist=HomeQ::Histogram.new(0,10,0.5) # lower bound/upper bound/class width
130
+ hist.push(51) # push data
131
+ hist.push(62)
132
+ hist.push(31)
133
+ 1.upto(9) do
134
+ hist << rand
135
+ end
136
+ puts hist.report # print histogram
137
+ end
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,185 @@
1
+ #############################################################################
2
+ #
3
+ # $Id: logger.rb 48 2008-11-19 05:11:59Z colin $
4
+ #
5
+ # Author:: Colin Steele (colin@colinsteele.org)
6
+ # Homepage::
7
+ #
8
+ # TODO: info
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2008 by Colin Steele. All Rights Reserved.
13
+ # colin@colinsteele.org
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+ #############################################################################
26
+
27
+ require 'singleton'
28
+
29
+ module HomeQ
30
+
31
+ module Base
32
+
33
+ module Logging
34
+
35
+ module HomeQ::Base::Commando::InstanceMethods
36
+ config_accessor :log_id
37
+ def log_level(*args)
38
+ HomeQ::Base::Logging::Logger.instance.log_level(*args)
39
+ end
40
+ def log_file(*args)
41
+ HomeQ::Base::Logging::Logger.instance.log_file(*args)
42
+ end
43
+ def syslog
44
+ HomeQ::Base::Logging::Logger.instance.syslog
45
+ end
46
+ document_command(:syslog, "Send logging through syslog")
47
+ document_command(:log_file, "Log to the specified file")
48
+ document_command(:log_level,
49
+ "Set log level (DEBUG < INFO < WARN < ERROR < FATAL)")
50
+ end
51
+
52
+ def logger
53
+ Logger.instance.logger
54
+ end
55
+
56
+ class Logger
57
+
58
+ PAT = "%d %l %c %m"
59
+
60
+ include Singleton
61
+ include Base::Configuration
62
+
63
+ begin
64
+
65
+ require 'log4r'
66
+ require 'log4r/configurator'
67
+
68
+ attr :logger
69
+
70
+ def initialize
71
+ # create a logger that logs to stdout
72
+ @id = config.log_id || File.basename($0)
73
+
74
+ # DEBUG < INFO < WARN < ERROR < FATAL
75
+ levels = [
76
+ :DEBUG4, :DEBUG3, :DEBUG2, :DEBUG1, :DEBUG,
77
+ :INFO, :WARN, :ERROR, :FATAL
78
+ ]
79
+ Log4r::Configurator.custom_levels(*levels)
80
+ @logger = Log4r::Logger.new(@id)
81
+ @logger.level = Log4r.const_get("INFO")
82
+ end
83
+
84
+ def stdout
85
+ o = Log4r::Outputter.stdout
86
+ o.formatter = Log4r::PatternFormatter.new(:pattern => PAT)
87
+ @logger.outputters << o
88
+ end
89
+
90
+ def syslog
91
+ with_warnings_suppressed do
92
+ levels = %w(DEBUG INFO WARN ERROR FATAL)
93
+ Log4r.class_eval {
94
+ remove_const('OFF')
95
+ Log4r::LNAMES.slice!(0..-1)
96
+ require 'log4r/outputter/syslogoutputter'
97
+ }
98
+ end
99
+ @id = config.log_id || File.basename($0)
100
+ logger = Log4r::Logger.new(@id)
101
+ o = Log4r::SyslogOutputter.new(@id)
102
+ o.formatter = Log4r::PatternFormatter.new(:pattern => PAT)
103
+ logger.outputters = o
104
+ @logger.info {
105
+ "Logging to syslog with USER facility."
106
+ }
107
+ logger.level = Log4r.const_get("INFO")
108
+ @logger = logger
109
+ end
110
+
111
+ def log_file(*args)
112
+ hash = {
113
+ :filename => args[0],
114
+ :trunc => false
115
+ }
116
+ o = Log4r::FileOutputter.new(@id, hash)
117
+ o.formatter = Log4r::PatternFormatter.new(:pattern => PAT)
118
+ @logger.outputters << o
119
+ @logger.info {
120
+ "Logging to #{args[0]}."
121
+ }
122
+ end
123
+
124
+ def log_level(*args)
125
+ return @level if args.empty?
126
+ if args[0].is_a?(String)
127
+ level = Log4r.const_get(args[0].upcase)
128
+ else
129
+ level = Log4r.const_get("INFO") - args[0].to_i
130
+ level = [level,0].max
131
+ level = [level,10].min
132
+ end
133
+ old_level = @logger.level
134
+ @logger.level = level
135
+ if old_level != level
136
+ @logger.info {
137
+ "Log level is #{Log4r::LNAMES[@logger.level]}"
138
+ }
139
+ end
140
+ Log4r::LNAMES[@logger.level]
141
+ end
142
+
143
+ def logger
144
+ @logger
145
+ end
146
+
147
+ # rescue LoadError
148
+ rescue => e
149
+
150
+ def debug(*args)
151
+ if block_given?
152
+ STDERR.puts yield
153
+ else
154
+ STDERR.puts args.join("\n")
155
+ end
156
+ end
157
+
158
+ %w(info warn error fatal debug1 debug2 debug3 debug4).each { |x|
159
+ module_eval("alias_method :#{x}, :debug")
160
+ }
161
+
162
+ def logger
163
+ self
164
+ end
165
+
166
+ end # begin block
167
+
168
+ def with_warnings_suppressed
169
+ saved_verbosity = $-v
170
+ $-v = nil
171
+ yield
172
+ ensure
173
+ $-v = saved_verbosity
174
+ end
175
+
176
+ end # Logger
177
+
178
+ end # Logging
179
+
180
+ end # Base
181
+
182
+ end # HomeQ
183
+
184
+
185
+
@@ -0,0 +1,297 @@
1
+ #!/usr/bin/ruby
2
+
3
+ #############################################################################
4
+ #
5
+ # $Id: homeq.rb 8 2008-08-27 20:15:22Z colin $
6
+ #
7
+ # Author:: Colin Steele (colin@colinsteele.org)
8
+ # Homepage::
9
+ #
10
+ # TODO: info
11
+ #
12
+ #----------------------------------------------------------------------------
13
+ #
14
+ # Copyright (C) 2008 by Colin Steele. All Rights Reserved.
15
+ # colin@colinsteele.org
16
+ #
17
+ # This program is free software; you can redistribute it and/or modify
18
+ # it under the terms of either: 1) the GNU General Public License
19
+ # as published by the Free Software Foundation; either version 2 of the
20
+ # License, or (at your option) any later version; or 2) Ruby's License.
21
+ #
22
+ # See the file COPYING for complete licensing information.
23
+ #
24
+ #---------------------------------------------------------------------------
25
+ #
26
+ #
27
+ #############################################################################
28
+
29
+ module HomeQ
30
+
31
+ class OHash
32
+
33
+ include Enumerable
34
+
35
+ def initialize
36
+ @keys = {}
37
+ @queue = []
38
+ end
39
+ def insert(key, value)
40
+ if @keys.member?(key)
41
+ raise ArgumentException.new("Duplicate key")
42
+ end
43
+ @queue << key
44
+ @keys[key] = value
45
+ end
46
+ alias_method :push, :insert
47
+ def delete(key)
48
+ @queue.delete(key)
49
+ @keys.delete(key)
50
+ end
51
+ def [](key)
52
+ @keys[key]
53
+ end
54
+ def []=(key, val)
55
+ if @keys.member?(key)
56
+ @keys[key] = val
57
+ else
58
+ insert(key, val)
59
+ end
60
+ end
61
+ def each
62
+ @queue.each {|k|
63
+ yield k, @keys[k]
64
+ }
65
+ end
66
+ def keys
67
+ @keys.keys
68
+ end
69
+ def length
70
+ @keys.length
71
+ end
72
+ alias_method :size, :length
73
+ def member?(key)
74
+ @keys.member?(key)
75
+ end
76
+ alias_method :has_key?, :member?
77
+ def pop
78
+ k = @queue.slice!(-1)
79
+ [k,@keys.delete(k)]
80
+ end
81
+ def unshift(k,v)
82
+ # Yes, could have called insert here and then manipulated @queue
83
+ # after, that would be more DRY. But this is *much* faster.
84
+ if @keys.member?(k)
85
+ raise ArgumentException.new("Duplicate key")
86
+ end
87
+ @queue.unshift(k)
88
+ @keys[k] = v
89
+ [k,v]
90
+ end
91
+ def shift
92
+ k = @queue.shift
93
+ [k,@keys.delete(k)]
94
+ end
95
+ def first
96
+ [@queue.first, self[@queue.first]]
97
+ end
98
+ def last
99
+ [@queue.last, self[@queue.last]]
100
+ end
101
+ end
102
+
103
+ end # module HomeQ
104
+
105
+ if $0 == __FILE__
106
+
107
+ require 'benchmark'
108
+ require 'rubygems'
109
+ require 'facets/dictionary'
110
+
111
+ array = (1..1000000).map { rand }
112
+ d = nil
113
+ h = nil
114
+ oh = nil
115
+
116
+ if nil
117
+ Benchmark.bmbm do |x|
118
+ len = 100000
119
+ x.report("unshift") {
120
+ a = []
121
+ 0.upto(len) {
122
+ a.push(rand)
123
+ }
124
+ }
125
+ x.report("insert") {
126
+ a = []
127
+ 0.upto(len) {
128
+ a.insert(0,rand)
129
+ }
130
+ }
131
+ end
132
+ exit
133
+ end
134
+
135
+ puts "\nINSERT"
136
+ Benchmark.bmbm do |x|
137
+ x.report("hash") {
138
+ h = Hash.new
139
+ array.each_with_index {|v,i|
140
+ h[i] = v
141
+ }
142
+ }
143
+ x.report("facets") {
144
+ d = Dictionary.new
145
+ array.each_with_index {|v,i|
146
+ d[i] = v
147
+ }
148
+ }
149
+ x.report("ohash") {
150
+ oh = HomeQ::OHash.new
151
+ array.each_with_index {|v,i|
152
+ oh[i] = v
153
+ }
154
+ }
155
+ end
156
+
157
+ puts "\nFIND"
158
+ Benchmark.bmbm do |x|
159
+ len = array.length
160
+ x.report("hash") {
161
+ array.each {
162
+ ind = rand(len)
163
+ h[ind]
164
+ }
165
+ }
166
+ x.report("facets") {
167
+ array.each {
168
+ ind = rand(len)
169
+ d[ind]
170
+ }
171
+ }
172
+ x.report("ohash") {
173
+ array.each {
174
+ ind = rand(len)
175
+ oh[ind]
176
+ }
177
+ }
178
+ end
179
+
180
+ puts "\nPUSH"
181
+ Benchmark.bmbm do |x|
182
+ x.report("hash") {
183
+ h = Hash.new
184
+ array.each_with_index {|v,i|
185
+ h[i] = v
186
+ }
187
+ }
188
+ x.report("facets") {
189
+ d = Dictionary.new
190
+ array.each_with_index {|v,i|
191
+ d.push(i,v)
192
+ }
193
+ }
194
+ x.report("ohash") {
195
+ oh = HomeQ::OHash.new
196
+ array.each_with_index {|v,i|
197
+ oh.push(i,v)
198
+ }
199
+ }
200
+ end
201
+
202
+ puts "\nUNSHIFT"
203
+ Benchmark.bmbm do |x|
204
+ x.report("hash") {
205
+ h = Hash.new
206
+ array.each_with_index {|v,i|
207
+ break if i > 10000
208
+ h[i] = v
209
+ }
210
+ }
211
+ x.report("facets") {
212
+ d = Dictionary.new
213
+ array.each_with_index {|v,i|
214
+ break if i > 10000
215
+ d.unshift(i,v)
216
+ }
217
+ }
218
+ x.report("ohash") {
219
+ oh = HomeQ::OHash.new
220
+ array.each_with_index {|v,i|
221
+ break if i > 10000
222
+ oh.unshift(i,v)
223
+ }
224
+ }
225
+ end
226
+
227
+ puts "\nPOP"
228
+ Benchmark.bmbm do |x|
229
+ x.report("facets pop x 10") {
230
+ 0.upto(10) { |i|
231
+ d.pop
232
+ }
233
+ }
234
+ x.report("ohash pop x 10000") {
235
+ 0.upto(10000) {
236
+ oh.pop
237
+ }
238
+ }
239
+ end
240
+
241
+ puts "\nSHIFT"
242
+ Benchmark.bmbm do |x|
243
+ x.report("facets shift x 10") {
244
+ 0.upto(10) { |i|
245
+ d.shift
246
+ }
247
+ }
248
+ x.report("ohash shift x 10000") {
249
+ 0.upto(10000) {
250
+ oh.shift
251
+ }
252
+ }
253
+ end
254
+
255
+ require 'test/unit/testsuite'
256
+ require 'test/unit'
257
+
258
+ class TC_MyTest < Test::Unit::TestCase
259
+ def test_simple
260
+ h = HomeQ::OHash.new
261
+ h.push(99,100)
262
+ assert_equal([99,100], h.pop)
263
+ assert_equal(0, h.length)
264
+ assert_equal([nil,nil], h.first)
265
+ end
266
+
267
+ def test_more
268
+ h = HomeQ::OHash.new
269
+ 100.upto(199) do |i|
270
+ h.push(i,i-99)
271
+ end
272
+ assert_equal([199,100], h.pop)
273
+ assert_equal(99, h.length)
274
+ assert_equal([100,1], h.first)
275
+ assert_equal([100,1], h.shift)
276
+ assert_equal([101,2], h.first)
277
+ assert_equal([:x,:y], h.unshift(:x, :y))
278
+ assert_equal([:x,:y], h.first)
279
+ assert_equal([:x,:y], h.shift)
280
+ assert_equal(98, h.length)
281
+ assert_equal([101,2], h.first)
282
+ assert_equal([198,99], h.last)
283
+ assert_equal(51, h.delete(150))
284
+ assert_equal(97, h.length)
285
+ assert_equal(:x, h[150] = :x)
286
+ assert_equal(:x, h[150])
287
+ assert_equal(:y, h[150] = :y)
288
+ assert_equal(:y, h[150])
289
+ assert_equal(98, h.length)
290
+ assert_equal(true, h.member?(150))
291
+ assert_equal(false, h.member?(:not_a_member))
292
+ assert_equal(true, h.keys.include?(198))
293
+ assert_equal(false, h.keys.include?(199))
294
+ assert_equal(false, h.member?(199))
295
+ end
296
+ end
297
+ end