updater 0.9.3.2 → 0.9.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/VERSION +1 -1
- data/lib/updater/fork_worker.rb +2 -1
- data/lib/updater/orm/mongo.rb +21 -12
- data/lib/updater/setup.rb +42 -15
- data/lib/updater/update.rb +44 -5
- data/lib/updater.rb +2 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/update_spec.rb +1 -1
- metadata +3 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.9.
|
1
|
+
0.9.4
|
data/lib/updater/fork_worker.rb
CHANGED
@@ -73,6 +73,7 @@ module Updater
|
|
73
73
|
stop(false)
|
74
74
|
false
|
75
75
|
when :USR2, :DATA #wake up a child and get to work
|
76
|
+
logger.info {"Master Process recieved job ready signal"}
|
76
77
|
@pipe.last.write_nonblock('.')
|
77
78
|
true
|
78
79
|
when :TTIN
|
@@ -142,7 +143,7 @@ module Updater
|
|
142
143
|
timeout = calc_timeout
|
143
144
|
logger.debug { "Sleeping for #{timeout}" }
|
144
145
|
ready, _1, _2 = IO.select(@wakeup_set, nil, nil, timeout)
|
145
|
-
return unless ready && ready.first #timeout hit, just wakeup and run maintance
|
146
|
+
return unless ready && ready.first #timeout hit or self_pipe alerted, just wakeup and run maintance
|
146
147
|
add_connection(ready.first) and return if ready.first.respond_to?(:accept) #open a new incomming connection
|
147
148
|
@signal_queue << :DATA unless ready.first == @self_pipe.first
|
148
149
|
loop {ready.first.read_nonblock(16 * 1024)}
|
data/lib/updater/orm/mongo.rb
CHANGED
@@ -32,7 +32,7 @@ module Updater
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def _id=(val)
|
35
|
-
val = BSON::
|
35
|
+
val = BSON::ObjectId.from_string(val.to_s) unless val.kind_of? BSON::ObjectId
|
36
36
|
@hash[:_id] = val
|
37
37
|
end
|
38
38
|
|
@@ -59,7 +59,7 @@ module Updater
|
|
59
59
|
job
|
60
60
|
end
|
61
61
|
end
|
62
|
-
_id = self.class.collection.save
|
62
|
+
_id = self.class.collection.save(@hash, :safe=>true)
|
63
63
|
end
|
64
64
|
|
65
65
|
def destroy
|
@@ -106,10 +106,10 @@ module Updater
|
|
106
106
|
|
107
107
|
private
|
108
108
|
# this method is calld from he chain asignment methods eg. failure=(chain)
|
109
|
-
# chain is an array which may contain BSON::
|
110
|
-
# For BSON::
|
109
|
+
# chain is an array which may contain BSON::ObjectId's or Updater::Update's or both
|
110
|
+
# For BSON::ObjectId's we cannot initialize them as this could leed to infinate loops.
|
111
111
|
# (an object pool would solve this problem, but feels like overkill)
|
112
|
-
# The final result must be a @hash containing all the BSON::
|
112
|
+
# The final result must be a @hash containing all the BSON::ObjectId' (forign keys)
|
113
113
|
# and possibly @failure containting all instanciated UpdaterUpdates read to be called
|
114
114
|
# or @failure set to nil with the chain instanciated on first use.
|
115
115
|
def build_chain_arrays(arr, build = false)
|
@@ -131,20 +131,20 @@ module Updater
|
|
131
131
|
[nil,output[:ids]]
|
132
132
|
end
|
133
133
|
|
134
|
-
# This method takes something that may be a reference to an instance(BSON::
|
134
|
+
# This method takes something that may be a reference to an instance(BSON::ObjectId/String),
|
135
135
|
# an instance its self (Updater::Update), or a Hash
|
136
|
-
# and returns a touple of the Updater::Update,BSON::
|
137
|
-
# This method will bot instanciate object from BSON::
|
136
|
+
# and returns a touple of the Updater::Update,BSON::ObjectId.
|
137
|
+
# This method will bot instanciate object from BSON::ObjectId's
|
138
138
|
# nor will it save Hashes inorder to obtain an ID (it will creat a new Updater::Update from the hash).
|
139
139
|
# Instead it will return nil in the appropriate place.
|
140
140
|
def rationalize_instance(val)
|
141
|
-
val = BSON::
|
142
|
-
case val #aval is the actual runable object, hval is a BSON::
|
141
|
+
val = BSON::ObjectId.fron_string(val) if val.kind_of? String
|
142
|
+
case val #aval is the actual runable object, hval is a BSON::ObjectId that we can put into the Database
|
143
143
|
when Updater::Update
|
144
144
|
val.params ? [val,[val.id,val.params]] : [val,val.id]
|
145
145
|
when Hash
|
146
146
|
[Updater::Update.new(val),val['_id']]
|
147
|
-
when BSON::
|
147
|
+
when BSON::ObjectId
|
148
148
|
[nil,val]
|
149
149
|
when Array
|
150
150
|
rationalize_instance(val[0]).tap do |ret|
|
@@ -227,7 +227,7 @@ module Updater
|
|
227
227
|
end
|
228
228
|
|
229
229
|
def get(id)
|
230
|
-
id = BSON::
|
230
|
+
id = BSON::ObjectId.from_string(id) if id.kind_of? String
|
231
231
|
new(@collection.find_one(id))
|
232
232
|
end
|
233
233
|
|
@@ -249,6 +249,7 @@ module Updater
|
|
249
249
|
|
250
250
|
def queue_time
|
251
251
|
nxt = @collection.find_one({:lock_name=>nil, :time=>{'$ne'=>nil}}, :sort=>[[:time, :asc]], :fields=>[:time])
|
252
|
+
# logger.debug {" the queue is empty"} unless nxt
|
252
253
|
return nil unless nxt
|
253
254
|
return 0 if nxt['time'] <= tnow
|
254
255
|
return nxt['time'] - tnow
|
@@ -267,6 +268,14 @@ module Updater
|
|
267
268
|
@collection.update({:lock_name=>worker.name},{'$unset'=>{:lock_name=>1}},:multi=>true)
|
268
269
|
end
|
269
270
|
|
271
|
+
def for(target,finder,args,name)
|
272
|
+
if name
|
273
|
+
@collection.find(:target=>target.to_s, :finder_args=>args,:name=>name)
|
274
|
+
else
|
275
|
+
@collection.find(:target=>target.to_s, :finder_args=>args)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
270
279
|
private
|
271
280
|
def tnow
|
272
281
|
Updater::Update.time.now.to_i
|
data/lib/updater/setup.rb
CHANGED
@@ -6,26 +6,33 @@ require 'erb'
|
|
6
6
|
module Updater
|
7
7
|
class Setup
|
8
8
|
class << self
|
9
|
+
#start a new server
|
9
10
|
def start(options={})
|
10
11
|
new(config_file(options), options).start
|
11
12
|
end
|
12
13
|
|
14
|
+
#stop the server
|
13
15
|
def stop(options={})
|
14
16
|
new(config_file(options), options).stop
|
15
17
|
end
|
16
18
|
|
19
|
+
# Used for testing. Will run through the entire setup process, but
|
20
|
+
# not actually start the server, but will log the resulting options.
|
17
21
|
def noop(options={})
|
18
22
|
new(config_file(options), options).noop
|
19
23
|
end
|
20
24
|
|
25
|
+
# Connect a client to a server
|
21
26
|
def client_setup(options = {})
|
22
27
|
new(config_file(options), options).client_setup
|
23
28
|
end
|
24
29
|
|
30
|
+
# pendeing
|
25
31
|
def monitor
|
26
32
|
|
27
33
|
end
|
28
|
-
|
34
|
+
|
35
|
+
# Retruns tha locaion of the config file.
|
29
36
|
def config_file(options = {})
|
30
37
|
if options[:config_file] && File.exists?(options[:config_file])
|
31
38
|
options[:config_file]
|
@@ -48,7 +55,7 @@ module Updater
|
|
48
55
|
@logger = @options[:logger] || Logger.new(@options[:log_file] || STDOUT)
|
49
56
|
level = Logger::SEV_LABEL.index(@options[:log_level].upcase) if @options[:log_level]
|
50
57
|
@logger.level = level || Logger::WARN unless @options[:logger] #only set this if we were not handed a logger
|
51
|
-
@logger.debug "Debugging output enabled"
|
58
|
+
@logger.debug "Debugging output enabled" unless @options[:logger]
|
52
59
|
Update.logger = @logger
|
53
60
|
end
|
54
61
|
|
@@ -80,25 +87,45 @@ module Updater
|
|
80
87
|
@logger.info "Updater Client is being initialized..."
|
81
88
|
set_orm
|
82
89
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
socket = UDPSocket.new()
|
88
|
-
socket.connect(@options[:host],@options[:udp])
|
89
|
-
Updater::Update.socket = socket
|
90
|
-
elsif @options[:tcp]
|
91
|
-
Updater::Update.socket = TCPSocket.new(@options[:host],@options[:tcp])
|
92
|
-
elsif @options[:remote]
|
93
|
-
raise NotImplimentedError #For future Authenticated Http Rest Server
|
94
|
-
end
|
90
|
+
Updater::Update.socket = socket_for_client
|
91
|
+
|
92
|
+
|
93
|
+
init_orm
|
95
94
|
|
96
95
|
#set PID
|
97
96
|
if File.exists? @options[:pid_file]
|
98
97
|
Updater::Update.pid = File.read(@options[:pid_file]).strip
|
99
98
|
end
|
100
99
|
|
101
|
-
|
100
|
+
Updater::Update.config_file = @config_file
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
def socket_for_client
|
105
|
+
if @options[:socket] && File.exists?(@options[:socket])
|
106
|
+
@logger.debug "Using UNIX Socket \"#{@options[:socket]}\""
|
107
|
+
return UNIXSocket.new(@options[:socket]) if File.exists?(@options[:socket]) && File.stat(@options[:socket]).socket?
|
108
|
+
end
|
109
|
+
if @options[:udp]
|
110
|
+
socket = UDPSocket.new()
|
111
|
+
socket.connect(@options[:host],@options[:udp])
|
112
|
+
begin
|
113
|
+
socket.write '.' #must test UDP sockets
|
114
|
+
return socket
|
115
|
+
rescue Errno::ECONNREFUSED
|
116
|
+
end
|
117
|
+
end
|
118
|
+
if @options[:tcp]
|
119
|
+
begin
|
120
|
+
return TCPSocket.new(@options[:host],@options[:tcp])
|
121
|
+
rescue Errno::ECONNREFUSED
|
122
|
+
end
|
123
|
+
end
|
124
|
+
if @options[:remote]
|
125
|
+
return nil
|
126
|
+
raise NotImplimentedError #For future Authenticated Http Rest Server
|
127
|
+
end
|
128
|
+
return nil
|
102
129
|
end
|
103
130
|
|
104
131
|
private
|
data/lib/updater/update.rb
CHANGED
@@ -212,6 +212,8 @@ module Updater
|
|
212
212
|
if inst
|
213
213
|
worker.logger.debug " running job #{inst.id}"
|
214
214
|
new(inst).run
|
215
|
+
else
|
216
|
+
worker.logger.debug " could not find a ready job in the datastore"
|
215
217
|
end
|
216
218
|
@orm.queue_time
|
217
219
|
ensure
|
@@ -405,6 +407,9 @@ module Updater
|
|
405
407
|
@orm.clear_all
|
406
408
|
end
|
407
409
|
|
410
|
+
# The name of the file to look for information if we loose the server
|
411
|
+
attr_accessor :config_file
|
412
|
+
|
408
413
|
#Sets the process id of the worker process if known. If this
|
409
414
|
#is set then an attempt will be made to signal the worker any
|
410
415
|
#time a new update is made.
|
@@ -431,12 +436,46 @@ module Updater
|
|
431
436
|
|
432
437
|
private
|
433
438
|
def signal_worker
|
434
|
-
|
435
|
-
|
436
|
-
@socket
|
437
|
-
|
438
|
-
|
439
|
+
errored = false
|
440
|
+
begin
|
441
|
+
if @socket
|
442
|
+
@socket.write '.'
|
443
|
+
logger.debug "Signaled Master Process Via Socket"
|
444
|
+
elsif @pid
|
445
|
+
Process::kill "USR2", @pid
|
446
|
+
logger.debug "Signaled Master Process Via PID"
|
447
|
+
else
|
448
|
+
signal_worker if connection_refresh
|
449
|
+
end
|
450
|
+
rescue SystemCallError
|
451
|
+
logger.warn "Lost Client Connection to Updater Server"
|
452
|
+
if connection_refresh && !errored
|
453
|
+
errored = true
|
454
|
+
retry
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
def connection_refresh
|
460
|
+
logger.debug "Connection Refresh Attempted"
|
461
|
+
@socket.close if @socket
|
462
|
+
@socket = nil; @pid = nil #assume the old server died
|
463
|
+
@connection_refresh ||= [1,Time.now-1]
|
464
|
+
delay, time = @connection_refresh
|
465
|
+
if Time.now >= time+delay
|
466
|
+
Setup.new(@config_file, :logger=>logger).client_setup
|
467
|
+
if @pid || @socket #assume we were successful and retry
|
468
|
+
@connection_refresh = nil
|
469
|
+
return true
|
470
|
+
else
|
471
|
+
logger.debug "Connection Refresh Failed"
|
472
|
+
#we are still not able to connect, don't try again for a while
|
473
|
+
@connection_refresh= [[delay*2,10*60].min,Time.now]
|
474
|
+
return false
|
475
|
+
end
|
439
476
|
end
|
477
|
+
logger.debug "Connection Refresh Waiting until #{time+delay}"
|
478
|
+
return false
|
440
479
|
end
|
441
480
|
|
442
481
|
# Given some instance return the information needed to recreate that target
|
data/lib/updater.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
data/spec/update_spec.rb
CHANGED
metadata
CHANGED
@@ -5,9 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 9
|
8
|
-
-
|
9
|
-
|
10
|
-
version: 0.9.3.2
|
8
|
+
- 4
|
9
|
+
version: 0.9.4
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- John F. Miller
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date:
|
17
|
+
date: 2011-02-14 00:00:00 -08:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|