feedupdater 0.1.0 → 0.2.0
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 +3 -0
- data/config/feed_updater.yml +7 -0
- data/lib/feed_updater/version.rb +1 -1
- data/lib/feed_updater.rb +219 -28
- metadata +2 -4
- data/config/feed_updater.pid +0 -1
data/CHANGELOG
CHANGED
data/config/feed_updater.yml
CHANGED
@@ -5,8 +5,15 @@ start_delay: false
|
|
5
5
|
# See the documentation for details.
|
6
6
|
load_script: example/custom_updater.rb
|
7
7
|
|
8
|
+
# Keep this set to 1 unless you're certain you need to set it higher.
|
9
|
+
# Never set it higher than 1 if you're on a shared server.
|
10
|
+
threads: 5
|
11
|
+
|
8
12
|
# This is the path to store the pid files.
|
9
13
|
pid_file_path: config
|
10
14
|
|
11
15
|
# This is the path to store the log files.
|
12
16
|
log_file_path: log
|
17
|
+
|
18
|
+
# Log level
|
19
|
+
log_level: 0
|
data/lib/feed_updater/version.rb
CHANGED
data/lib/feed_updater.rb
CHANGED
@@ -55,6 +55,41 @@ if !defined?(FeedTools::FEED_TOOLS_VERSION)
|
|
55
55
|
end
|
56
56
|
|
57
57
|
require 'benchmark'
|
58
|
+
require 'thread'
|
59
|
+
require 'logger'
|
60
|
+
|
61
|
+
class FeedUpdaterLogger < Logger
|
62
|
+
attr_accessor :prefix
|
63
|
+
|
64
|
+
alias_method :old_log, :log
|
65
|
+
def log(level, message)
|
66
|
+
if defined?(@prefix) && @prefix != nil
|
67
|
+
self.old_log(level, self.prefix + message)
|
68
|
+
else
|
69
|
+
self.old_log(level, message)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def debug(message)
|
74
|
+
self.log(0, message)
|
75
|
+
end
|
76
|
+
|
77
|
+
def info(message)
|
78
|
+
self.log(1, message)
|
79
|
+
end
|
80
|
+
|
81
|
+
def warn(message)
|
82
|
+
self.log(2, message)
|
83
|
+
end
|
84
|
+
|
85
|
+
def error(message)
|
86
|
+
self.log(3, message)
|
87
|
+
end
|
88
|
+
|
89
|
+
def fatal(message)
|
90
|
+
self.log(4, message)
|
91
|
+
end
|
92
|
+
end
|
58
93
|
|
59
94
|
module FeedTools
|
60
95
|
# A simple daemon for scheduled updating of feeds.
|
@@ -127,7 +162,11 @@ module FeedTools
|
|
127
162
|
# Returns the logger object.
|
128
163
|
def logger()
|
129
164
|
if !defined?(@logger) || @logger.nil?
|
130
|
-
@logger =
|
165
|
+
@logger = FeedUpdaterLogger.new(self.log_file)
|
166
|
+
@logger.level = self.updater_options[:log_level]
|
167
|
+
@logger.datetime_format = nil
|
168
|
+
@logger.progname = nil
|
169
|
+
@logger.prefix = "FeedUpdater".ljust(20)
|
131
170
|
end
|
132
171
|
return @logger
|
133
172
|
end
|
@@ -139,7 +178,11 @@ module FeedTools
|
|
139
178
|
self.logger.close()
|
140
179
|
rescue IOError
|
141
180
|
end
|
142
|
-
@logger =
|
181
|
+
@logger = FeedUpdaterLogger.new(self.log_file)
|
182
|
+
@logger.level = self.updater_options[:log_level]
|
183
|
+
@logger.datetime_format = nil
|
184
|
+
@logger.progname = nil
|
185
|
+
@logger.prefix = "FeedUpdater".ljust(20)
|
143
186
|
end
|
144
187
|
|
145
188
|
# Returns a list of feeds to be updated.
|
@@ -174,7 +217,9 @@ module FeedTools
|
|
174
217
|
def updater_options()
|
175
218
|
if !defined?(@updater_options) || @updater_options.nil?
|
176
219
|
@updater_options = {
|
177
|
-
:start_delay => true
|
220
|
+
:start_delay => true,
|
221
|
+
:thread => 1,
|
222
|
+
:log_level => 0
|
178
223
|
}
|
179
224
|
end
|
180
225
|
return @updater_options
|
@@ -234,6 +279,7 @@ module FeedTools
|
|
234
279
|
|
235
280
|
# Starts the daemon.
|
236
281
|
def start()
|
282
|
+
self.logger.prefix = "FeedUpdater".ljust(20)
|
237
283
|
if !defined?(@@on_update) || @@on_update.nil?
|
238
284
|
raise "No on_update handler block given."
|
239
285
|
end
|
@@ -241,6 +287,9 @@ module FeedTools
|
|
241
287
|
puts "FeedUpdater is already running."
|
242
288
|
return self.pid
|
243
289
|
end
|
290
|
+
if defined?(ActiveRecord)
|
291
|
+
ActiveRecord::Base.allow_concurrency = true
|
292
|
+
end
|
244
293
|
|
245
294
|
@initial_directory = File.expand_path(".")
|
246
295
|
|
@@ -280,9 +329,13 @@ module FeedTools
|
|
280
329
|
self.update_feeds()
|
281
330
|
end
|
282
331
|
self.logger.info(
|
283
|
-
"#{@feed_href_list.size}
|
332
|
+
"#{@feed_href_list.size} feed(s) updated " +
|
284
333
|
"in #{result.real.round} seconds.")
|
285
|
-
|
334
|
+
if !defined?(@feed_href_list_override) ||
|
335
|
+
!@feed_href_list_override
|
336
|
+
@feed_href_list = nil
|
337
|
+
end
|
338
|
+
ObjectSpace.garbage_collect()
|
286
339
|
sleepy_time = 1.hour - result.real.round
|
287
340
|
if sleepy_time > 0
|
288
341
|
self.logger.info(
|
@@ -304,11 +357,16 @@ module FeedTools
|
|
304
357
|
else
|
305
358
|
@application.start()
|
306
359
|
end
|
360
|
+
self.logger.prefix = nil
|
361
|
+
self.logger.level = 0
|
307
362
|
self.logger.info("-" * 79)
|
308
363
|
self.logger.info("Daemon started, " +
|
309
364
|
"FeedUpdater #{FeedTools::FEED_UPDATER_VERSION::STRING} / " +
|
310
365
|
"FeedTools #{FeedTools::FEED_TOOLS_VERSION::STRING}")
|
311
366
|
self.logger.info(" @ #{Time.now.utc.to_s}")
|
367
|
+
self.logger.info("-" * 79)
|
368
|
+
self.logger.level = self.updater_options[:log_level]
|
369
|
+
self.logger.prefix = "FeedUpdater".ljust(20)
|
312
370
|
@status = :running
|
313
371
|
return self.pid
|
314
372
|
end
|
@@ -340,7 +398,10 @@ module FeedTools
|
|
340
398
|
end
|
341
399
|
rescue Exception
|
342
400
|
end
|
401
|
+
self.logger.prefix = "FeedUpdater".ljust(20)
|
402
|
+
self.logger.level = 0
|
343
403
|
self.logger.info("Daemon stopped.")
|
404
|
+
self.logger.level = self.updater_options[:log_level]
|
344
405
|
@status = :stopped
|
345
406
|
return nil if self.application.nil?
|
346
407
|
begin
|
@@ -358,40 +419,170 @@ module FeedTools
|
|
358
419
|
|
359
420
|
# Updates all of the feeds.
|
360
421
|
def update_feeds()
|
422
|
+
self.logger.prefix = "FeedUpdater".ljust(20)
|
423
|
+
ObjectSpace.garbage_collect()
|
361
424
|
if defined?(@feed_href_list_override) && @feed_href_list_override
|
362
425
|
self.feed_href_list()
|
363
426
|
else
|
427
|
+
self.logger.info("Loading default feed list...")
|
364
428
|
@feed_href_list =
|
365
|
-
|
366
|
-
|
429
|
+
(FeedTools.feed_cache.find(:all).collect do |cache_object|
|
430
|
+
cache_object.href
|
431
|
+
end)
|
432
|
+
end
|
433
|
+
self.logger.info("Updating #{@feed_href_list.size} feed(s)...")
|
434
|
+
ObjectSpace.garbage_collect()
|
435
|
+
|
436
|
+
threads = []
|
437
|
+
thread_slices = []
|
438
|
+
thread_slice_size =
|
439
|
+
(@feed_href_list.size / self.updater_options[:threads])
|
440
|
+
|
441
|
+
for i in 0...self.updater_options[:threads]
|
442
|
+
if i != self.updater_options[:threads] - 1
|
443
|
+
thread_slices << @feed_href_list[
|
444
|
+
(i * thread_slice_size)...((i + 1) * thread_slice_size)]
|
445
|
+
else
|
446
|
+
thread_slices << @feed_href_list[
|
447
|
+
(i * thread_slice_size)..-1]
|
367
448
|
end
|
368
449
|
end
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
450
|
+
ObjectSpace.garbage_collect()
|
451
|
+
|
452
|
+
begin_updating = false
|
453
|
+
self.logger.info(
|
454
|
+
"Starting up #{self.updater_options[:threads]} thread(s)...")
|
455
|
+
|
456
|
+
mutex = Mutex.new
|
457
|
+
for i in 0...self.updater_options[:threads]
|
458
|
+
updater_thread = Thread.new do
|
459
|
+
self.logger.level = self.updater_options[:log_level]
|
460
|
+
self.logger.datetime_format = "%s"
|
461
|
+
self.logger.progname = "FeedUpdater".ljust(20)
|
462
|
+
|
463
|
+
while !Thread.current.respond_to?(:thread_id) &&
|
464
|
+
begin_updating == false
|
465
|
+
Thread.pass
|
466
|
+
end
|
467
|
+
mutex.synchronize do
|
468
|
+
self.logger.prefix = "Thread #{Thread.current.thread_id} ".ljust(20)
|
469
|
+
self.logger.info("Thread started.")
|
470
|
+
|
471
|
+
begin
|
472
|
+
FeedTools.feed_cache.initialize_cache()
|
473
|
+
if !FeedTools.feed_cache.set_up_correctly?
|
474
|
+
self.logger.info("Problem with cache connection...")
|
475
|
+
end
|
476
|
+
rescue Exception => error
|
386
477
|
self.logger.info(error)
|
387
478
|
end
|
479
|
+
|
480
|
+
self.logger.info(
|
481
|
+
"Thread ##{Thread.current.thread_id} handling " +
|
482
|
+
"#{thread_slices[Thread.current.thread_id].size} feeds...")
|
388
483
|
end
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
484
|
+
|
485
|
+
ObjectSpace.garbage_collect()
|
486
|
+
Thread.pass
|
487
|
+
href_list = thread_slices[Thread.current.thread_id]
|
488
|
+
|
489
|
+
for i in 0...href_list.size
|
490
|
+
href = nil
|
491
|
+
progress = nil
|
492
|
+
mutex.synchronize do
|
493
|
+
href = href_list[i]
|
494
|
+
Thread.current.progress =
|
495
|
+
(href_list.index(href).to_f / href_list.size.to_f) * 100
|
496
|
+
progress = sprintf("%.2f", Thread.current.progress)
|
497
|
+
end
|
498
|
+
begin
|
499
|
+
begin
|
500
|
+
feed = nil
|
501
|
+
feed_load_benchmark = Benchmark.measure do
|
502
|
+
feed = FeedTools::Feed.open(href)
|
503
|
+
end
|
504
|
+
Thread.pass
|
505
|
+
if feed.live?
|
506
|
+
unless @@on_update.nil?
|
507
|
+
mutex.synchronize do
|
508
|
+
progress = sprintf("%.2f", Thread.current.progress)
|
509
|
+
self.logger.prefix = ("Thread #{Thread.current.thread_id} " +
|
510
|
+
"(#{progress}%)"
|
511
|
+
).ljust(20)
|
512
|
+
self.cloaker(&(@@on_update)).bind(self).call(
|
513
|
+
feed, feed_load_benchmark.real)
|
514
|
+
end
|
515
|
+
end
|
516
|
+
else
|
517
|
+
mutex.synchronize do
|
518
|
+
progress = sprintf("%.2f", Thread.current.progress)
|
519
|
+
self.logger.prefix = ("Thread #{Thread.current.thread_id} " +
|
520
|
+
"(#{progress}%)"
|
521
|
+
).ljust(20)
|
522
|
+
self.logger.info(
|
523
|
+
"'#{href}' unchanged, skipping.")
|
524
|
+
end
|
525
|
+
end
|
526
|
+
rescue Exception => error
|
527
|
+
mutex.synchronize do
|
528
|
+
progress = sprintf("%.2f", Thread.current.progress)
|
529
|
+
self.logger.prefix = ("Thread #{Thread.current.thread_id} " +
|
530
|
+
"(#{progress}%)"
|
531
|
+
).ljust(20)
|
532
|
+
if @@on_error != nil
|
533
|
+
self.cloaker(&(@@on_error)).bind(self).call(href, error)
|
534
|
+
else
|
535
|
+
self.logger.error("Error updating '#{href}':")
|
536
|
+
self.logger.error(error.class.name + ": " + error.message)
|
537
|
+
self.logger.error(error.class.backtrace)
|
538
|
+
end
|
539
|
+
end
|
540
|
+
end
|
541
|
+
rescue Exception => error
|
542
|
+
mutex.synchronize do
|
543
|
+
progress = sprintf("%.2f", Thread.current.progress)
|
544
|
+
self.logger.prefix = ("Thread #{Thread.current.thread_id} " +
|
545
|
+
"(#{progress}%)"
|
546
|
+
).ljust(20)
|
547
|
+
self.logger.fatal("Critical unhandled error.")
|
548
|
+
self.logger.fatal("Error updating '#{href}':")
|
549
|
+
self.logger.fatal(error.class.name + ": " + error.message)
|
550
|
+
self.logger.fatal(error.class.backtrace)
|
551
|
+
end
|
552
|
+
end
|
553
|
+
ObjectSpace.garbage_collect()
|
554
|
+
Thread.pass
|
555
|
+
end
|
556
|
+
end
|
557
|
+
threads << updater_thread
|
558
|
+
class <<updater_thread
|
559
|
+
attr_accessor :thread_id
|
560
|
+
attr_accessor :progress
|
561
|
+
end
|
562
|
+
updater_thread.thread_id = i
|
563
|
+
end
|
564
|
+
mutex.synchronize do
|
565
|
+
self.logger.prefix = "FeedUpdater".ljust(20)
|
566
|
+
self.logger.info(
|
567
|
+
"#{threads.size} thread(s) successfully started...")
|
568
|
+
begin_updating = true
|
569
|
+
end
|
570
|
+
Thread.pass
|
571
|
+
|
572
|
+
ObjectSpace.garbage_collect()
|
573
|
+
Thread.pass
|
574
|
+
for i in 0...threads.size
|
575
|
+
mutex.synchronize do
|
576
|
+
self.logger.prefix = "FeedUpdater".ljust(20)
|
577
|
+
self.logger.info(
|
578
|
+
"Joining on thread #{threads[i].thread_id}...")
|
393
579
|
end
|
580
|
+
threads[i].join
|
394
581
|
end
|
582
|
+
self.logger.prefix = "FeedUpdater".ljust(20)
|
583
|
+
ObjectSpace.garbage_collect()
|
584
|
+
|
585
|
+
self.logger.progname = nil
|
395
586
|
unless @@on_complete.nil?
|
396
587
|
self.cloaker(&(@@on_complete)).bind(self).call(@feed_href_list)
|
397
588
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: feedupdater
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2006-04-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2006-04-17 00:00:00 -07:00
|
8
8
|
summary: Automatic feed updater daemon.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -32,7 +32,6 @@ files:
|
|
32
32
|
- bin
|
33
33
|
- CHANGELOG
|
34
34
|
- config
|
35
|
-
- doc
|
36
35
|
- example
|
37
36
|
- lib
|
38
37
|
- log
|
@@ -55,7 +54,6 @@ files:
|
|
55
54
|
- lib/feed_updater/vendor/daemons/pid.rb
|
56
55
|
- lib/feed_updater/vendor/daemons/pidfile.rb
|
57
56
|
- lib/feed_updater/vendor/daemons/pidmem.rb
|
58
|
-
- config/feed_updater.pid
|
59
57
|
- config/feed_updater.yml
|
60
58
|
- example/custom_updater.rb
|
61
59
|
test_files: []
|
data/config/feed_updater.pid
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
617
|