ThiagoLelis-backgroundjob 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/attributes.rb ADDED
@@ -0,0 +1,118 @@
1
+ module Attributes
2
+ Attributes::VERSION = '5.0.0' unless defined? Attributes::VERSION
3
+ def self.version() Attributes::VERSION end
4
+
5
+ class List < ::Array
6
+ def << element
7
+ super
8
+ self
9
+ ensure
10
+ uniq!
11
+ index!
12
+ end
13
+ def index!
14
+ @index ||= Hash.new
15
+ each{|element| @index[element] = true}
16
+ end
17
+ def include? element
18
+ @index ||= Hash.new
19
+ @index[element] ? true : false
20
+ end
21
+ def initializers
22
+ @initializers ||= Hash.new
23
+ end
24
+ end
25
+
26
+ def attributes *a, &b
27
+ unless a.empty?
28
+ returned = Hash.new
29
+
30
+ hashes, names = a.partition{|x| Hash === x}
31
+ names_and_defaults = {}
32
+ hashes.each{|h| names_and_defaults.update h}
33
+ names.flatten.compact.each{|name| names_and_defaults.update name => nil}
34
+
35
+ initializers = __attributes__.initializers
36
+
37
+ names_and_defaults.each do |name, default|
38
+ raise NameError, "bad instance variable name '@#{ name }'" if "@#{ name }" =~ %r/[!?=]$/o
39
+ name = name.to_s
40
+
41
+ initialize = b || lambda { default }
42
+ initializer = lambda do |this|
43
+ Object.instance_method('instance_eval').bind(this).call &initialize
44
+ end
45
+ initializer_id = initializer.object_id
46
+ __attributes__.initializers[name] = initializer
47
+
48
+ module_eval <<-code
49
+ def #{ name }=(*value, &block)
50
+ value.unshift block if block
51
+ @#{ name } = value.first
52
+ end
53
+ code
54
+
55
+ module_eval <<-code
56
+ def #{ name }(*value, &block)
57
+ value.unshift block if block
58
+ return self.send('#{ name }=', value.first) unless value.empty?
59
+ #{ name }! unless defined? @#{ name }
60
+ @#{ name }
61
+ end
62
+ code
63
+
64
+ module_eval <<-code
65
+ def #{ name }!
66
+ initializer = ObjectSpace._id2ref #{ initializer_id }
67
+ self.#{ name } = initializer.call(self)
68
+ @#{ name }
69
+ end
70
+ code
71
+
72
+ module_eval <<-code
73
+ def #{ name }?
74
+ #{ name }
75
+ end
76
+ code
77
+
78
+ attributes << name
79
+ returned[name] = initializer
80
+ end
81
+
82
+ returned
83
+ else
84
+ begin
85
+ __attribute_list__
86
+ rescue NameError
87
+ singleton_class =
88
+ class << self
89
+ self
90
+ end
91
+ klass = self
92
+ singleton_class.module_eval do
93
+ attribute_list = List.new
94
+ define_method('attribute_list'){ klass == self ? attribute_list : raise(NameError) }
95
+ alias_method '__attribute_list__', 'attribute_list'
96
+ end
97
+ __attribute_list__
98
+ end
99
+ end
100
+ end
101
+
102
+ %w( __attributes__ __attribute__ attribute ).each{|dst| alias_method dst, 'attributes'}
103
+ end
104
+
105
+ class Object
106
+ def attributes *a, &b
107
+ sc =
108
+ class << self
109
+ self
110
+ end
111
+ sc.attributes *a, &b
112
+ end
113
+ %w( __attributes__ __attribute__ attribute ).each{|dst| alias_method dst, 'attributes'}
114
+ end
115
+
116
+ class Module
117
+ include Attributes
118
+ end
data/lib/bj.rb CHANGED
@@ -3,7 +3,7 @@ unless defined? Bj
3
3
  #
4
4
  # constants and associated attrs
5
5
  #
6
- Bj::VERSION = "1.0.1" #unless defined? Bj::VERSION
6
+ Bj::VERSION = "1.0.4" #unless defined? Bj::VERSION
7
7
  def self.version() Bj::VERSION end
8
8
 
9
9
  Bj::LIBDIR = File.expand_path(File::join(File.dirname(__FILE__), "bj")) + File::SEPARATOR unless
data/lib/bj/runner.rb CHANGED
@@ -183,13 +183,13 @@ class Bj
183
183
  job = thread = stdout = stderr = nil
184
184
 
185
185
  Bj.transaction(options) do
186
- now = Time.now
186
+ now = Util.now
187
187
 
188
- job = Bj::Table::Job.find :first,
188
+ job = Bj::Table::Job.find_first_and_lock(
189
189
  :conditions => ["state = ? and submitted_at <= ?", "pending", now],
190
190
  :order => "priority DESC, submitted_at ASC",
191
191
  :limit => 1,
192
- :lock => true
192
+ :lock => true)
193
193
  throw :no_jobs unless job
194
194
 
195
195
 
@@ -200,7 +200,7 @@ class Bj
200
200
  stdin = job.stdin || ''
201
201
  stdout = job.stdout || ''
202
202
  stderr = job.stderr || ''
203
- started_at = Time.now
203
+ started_at = Util.now
204
204
 
205
205
  thread = Util.start command, :cwd=>Bj.rails_root, :env=>env, :stdin=>stdin, :stdout=>stdout, :stderr=>stderr
206
206
 
@@ -213,7 +213,7 @@ class Bj
213
213
  end
214
214
 
215
215
  exit_status = thread.value
216
- finished_at = Time.now
216
+ finished_at = Util.now
217
217
 
218
218
  Bj.transaction(options) do
219
219
  job = Bj::Table::Job.find job.id
@@ -287,7 +287,7 @@ class Bj
287
287
 
288
288
  def fill_morgue
289
289
  Bj.transaction do
290
- now = Time.now
290
+ now = Util.now
291
291
  jobs = Bj::Table::Job.find :all,
292
292
  :conditions => ["state = 'running' and runner = ?", Bj.hostname]
293
293
  jobs.each do |job|
@@ -309,7 +309,7 @@ class Bj
309
309
 
310
310
  def archive_jobs
311
311
  Bj.transaction do
312
- now = Time.now
312
+ now = Util.now
313
313
  too_old = now - Bj.ttl
314
314
  jobs = Bj::Table::Job.find :all,
315
315
  :conditions => ["(state = 'finished' or state = 'dead') and submitted_at < ?", too_old]
data/lib/bj/table.rb CHANGED
@@ -62,6 +62,24 @@ class Bj
62
62
  def reverse_each *a, &b
63
63
  list.reverse.each *a, &b
64
64
  end
65
+
66
+ # find(:first, :lock => true) does not work in oracle because
67
+ # of the implicit usage of :limit. instead we have to find :all
68
+ # and grab the first element returned. this is okay because the
69
+ # conditions supplied to the find will return a small result set,
70
+ # thus minimizing superfluous row locks.
71
+ def find_first_and_lock(options = {})
72
+ options[:lock] = true
73
+ db_config = configurations[Bj.rails_env.to_s]
74
+ case db_config['adapter']
75
+ when 'oracle','oci'
76
+ options.delete(:limit)
77
+ find(:all, options).first
78
+ else
79
+ find(:first, options)
80
+ end
81
+ end
82
+
65
83
  end
66
84
  send :extend, ClassMethods
67
85
 
@@ -96,25 +114,26 @@ class Bj
96
114
  migration {
97
115
  define_method :up do
98
116
  create_table table.table_name, :primary_key => table.primary_key, :force => true do |t|
99
- t.column "command" , :text
100
117
 
101
- t.column "state" , :text
118
+ t.column "command" , :string, :limit => 2000
119
+
120
+ t.column "state" , :string, :limit => 255
102
121
  t.column "priority" , :integer
103
- t.column "tag" , :text
122
+ t.column "tag" , :string, :limit => 1000
104
123
  t.column "is_restartable" , :integer
105
124
 
106
- t.column "submitter" , :text
107
- t.column "runner" , :text
125
+ t.column "submitter" , :string, :limit => 255
126
+ t.column "runner" , :string, :limit => 255
108
127
  t.column "pid" , :integer
109
128
 
110
129
  t.column "submitted_at" , :datetime
111
130
  t.column "started_at" , :datetime
112
131
  t.column "finished_at" , :datetime
113
132
 
114
- t.column "env" , :text
115
- t.column "stdin" , :text
116
- t.column "stdout" , :text
117
- t.column "stderr" , :text
133
+ t.column "env" , :string, :limit => 4000
134
+ t.column "stdin" , :string, :limit => 4000
135
+ t.column "stdout" , :string, :limit => 4000
136
+ t.column "stderr" , :string, :limit => 4000
118
137
  t.column "exit_status" , :integer
119
138
  end
120
139
  end
@@ -145,9 +164,10 @@ class Bj
145
164
  :tag => "",
146
165
  :is_restartable => true,
147
166
  :submitter => Bj.hostname,
148
- :submitted_at => Time.now,
167
+ :submitted_at => Time.now
149
168
  }
150
169
  end
170
+
151
171
  end
152
172
  send :extend, ClassMethods
153
173
 
@@ -171,15 +191,15 @@ class Bj
171
191
  migration {
172
192
  define_method(:up) do
173
193
  create_table table.table_name, :primary_key => table.primary_key, :force => true do |t|
174
- t.column "command" , :text
194
+ t.column "command" , :string, :limit => 2000
175
195
 
176
- t.column "state" , :text
196
+ t.column "state" , :string, :limit => 255
177
197
  t.column "priority" , :integer
178
- t.column "tag" , :text
198
+ t.column "tag" , :string, :limit => 1000
179
199
  t.column "is_restartable" , :integer
180
200
 
181
- t.column "submitter" , :text
182
- t.column "runner" , :text
201
+ t.column "submitter" , :string, :limit => 255
202
+ t.column "runner" , :string, :limit => 255
183
203
  t.column "pid" , :integer
184
204
 
185
205
  t.column "submitted_at" , :datetime
@@ -187,10 +207,10 @@ class Bj
187
207
  t.column "finished_at" , :datetime
188
208
  t.column "archived_at" , :datetime
189
209
 
190
- t.column "env" , :text
191
- t.column "stdin" , :text
192
- t.column "stdout" , :text
193
- t.column "stderr" , :text
210
+ t.column "env" , :string, :limit => 4000
211
+ t.column "stdin" , :string, :limit => 4000
212
+ t.column "stdout" , :string, :limit => 4000
213
+ t.column "stderr" , :string, :limit => 4000
194
214
  t.column "exit_status" , :integer
195
215
  end
196
216
  end
@@ -209,10 +229,10 @@ class Bj
209
229
  migration {
210
230
  define_method(:up) do
211
231
  create_table table.table_name, :primary_key => table.primary_key, :force => true do |t|
212
- t.column "hostname" , :text
213
- t.column "key" , :text
214
- t.column "value" , :text
215
- t.column "cast" , :text
232
+ t.column "hostname" , :string, :limit => 255
233
+ t.column "key" , :string, :limit => 255
234
+ t.column "value" , :string, :limit => 4000
235
+ t.column "cast" , :string, :limit => 255
216
236
  end
217
237
 
218
238
  begin
@@ -266,7 +286,7 @@ class Bj
266
286
  transaction do
267
287
  options.to_options!
268
288
  hostname = options[:hostname] || Bj.hostname
269
- record = find :first, :conditions => conditions(:key => key, :hostname => hostname), :lock => true
289
+ record = find_first_and_lock :conditions => conditions(:key => key, :hostname => hostname), :lock => true
270
290
  cast = options[:cast] || cast_for(value)
271
291
  key = key.to_s
272
292
  value = value.to_s
@@ -283,7 +303,7 @@ class Bj
283
303
 
284
304
  def delete key
285
305
  transaction do
286
- record = find :first, :conditions => conditions(:key => key), :lock => true
306
+ record = find_first_and_lock :conditions => conditions(:key => key), :lock => true
287
307
  if record
288
308
  record.destroy
289
309
  record
data/lib/bj/util.rb CHANGED
@@ -105,6 +105,10 @@ class Bj
105
105
  b = e.backtrace.join("\n") rescue ""
106
106
  "#{ m }(#{ c })\n#{ b }"
107
107
  end
108
+
109
+ def now
110
+ Bj.config["utc"] ? Time.now.utc : Time.now
111
+ end
108
112
  end
109
113
  send :extend, ModuleMethods
110
114
  end
data/lib/fattr.rb ADDED
@@ -0,0 +1,153 @@
1
+ module Fattr
2
+ Fattr::VERSION = '1.0.3' unless Fattr.const_defined?(:VERSION)
3
+ def self.version() Fattr::VERSION end
4
+
5
+ class List < ::Array
6
+ def << element
7
+ super
8
+ self
9
+ ensure
10
+ uniq!
11
+ index!
12
+ end
13
+
14
+ def index!
15
+ @index ||= Hash.new
16
+ each{|element| @index[element] = true}
17
+ end
18
+
19
+ def include? element
20
+ @index ||= Hash.new
21
+ @index[element] ? true : false
22
+ end
23
+
24
+ def initializers
25
+ @initializers ||= Hash.new
26
+ end
27
+ end
28
+
29
+ def fattrs *a, &b
30
+ unless a.empty?
31
+ returned = Hash.new
32
+
33
+ hashes, names = a.partition{|x| Hash === x}
34
+ names_and_defaults = {}
35
+ hashes.each{|h| names_and_defaults.update h}
36
+ names.flatten.compact.each{|name| names_and_defaults.update name => nil}
37
+
38
+ initializers = __fattrs__.initializers
39
+
40
+ names_and_defaults.each do |name, default|
41
+ raise NameError, "bad instance variable name '@#{ name }'" if "@#{ name }" =~ %r/[!?=]$/o
42
+ name = name.to_s
43
+
44
+ initialize = b || lambda { default }
45
+ initializer = lambda do |this|
46
+ Object.instance_method('instance_eval').bind(this).call &initialize
47
+ end
48
+ initializer_id = initializer.object_id
49
+ __fattrs__.initializers[name] = initializer
50
+
51
+ compile = lambda do |code|
52
+ begin
53
+ module_eval code
54
+ rescue SyntaxError
55
+ raise SyntaxError, "\n#{ code }\n"
56
+ end
57
+ end
58
+
59
+ # setter, block invocation caches block
60
+ code = <<-code
61
+ def #{ name }=(*value, &block)
62
+ value.unshift block if block
63
+ @#{ name } = value.first
64
+ end
65
+ code
66
+ compile[code]
67
+
68
+ # getter, providing a value or block causes it to acts as setter
69
+ code = <<-code
70
+ def #{ name }(*value, &block)
71
+ value.unshift block if block
72
+ return self.send('#{ name }=', value.first) unless value.empty?
73
+ #{ name }! unless defined? @#{ name }
74
+ @#{ name }
75
+ end
76
+ code
77
+ compile[code]
78
+
79
+ # bang method re-calls any initializer given at declaration time
80
+ code = <<-code
81
+ def #{ name }!
82
+ initializer = ObjectSpace._id2ref #{ initializer_id }
83
+ self.#{ name } = initializer.call(self)
84
+ @#{ name }
85
+ end
86
+ code
87
+ compile[code]
88
+
89
+ # query simply defers to getter - cast to bool
90
+ code = <<-code
91
+ def #{ name }?
92
+ self.#{ name }
93
+ end
94
+ code
95
+ compile[code]
96
+
97
+ fattrs << name
98
+ returned[name] = initializer
99
+ end
100
+
101
+ returned
102
+ else
103
+ begin
104
+ __fattr_list__
105
+ rescue NameError
106
+ singleton_class =
107
+ class << self
108
+ self
109
+ end
110
+ klass = self
111
+ singleton_class.module_eval do
112
+ fattr_list = List.new
113
+ define_method('fattr_list'){ klass == self ? fattr_list : raise(NameError) }
114
+ alias_method '__fattr_list__', 'fattr_list'
115
+ end
116
+ __fattr_list__
117
+ end
118
+ end
119
+ end
120
+
121
+ %w( __fattrs__ __fattr__ fattr ).each{|dst| alias_method dst, 'fattrs'}
122
+ end
123
+
124
+ class Module
125
+ include Fattr
126
+
127
+ def Fattrs(*a, &b)
128
+ class << self
129
+ self
130
+ end.module_eval do
131
+ fattrs(*a, &b)
132
+ end
133
+ end
134
+
135
+ def Fattr(*a, &b)
136
+ class << self
137
+ self
138
+ end.module_eval do
139
+ fattr(*a, &b)
140
+ end
141
+ end
142
+ end
143
+
144
+ class Object
145
+ def fattrs *a, &b
146
+ sc =
147
+ class << self
148
+ self
149
+ end
150
+ sc.fattrs *a, &b
151
+ end
152
+ %w( __fattrs__ __fattr__ fattr ).each{|dst| alias_method dst, 'fattrs'}
153
+ end