Skip to content

Commit b1a21ce

Browse files
committed
Use cache to avoid duplicate URL checks. Refactor
1 parent 8465f11 commit b1a21ce

3 files changed

Lines changed: 44 additions & 16 deletions

File tree

lib/link_checker.rb

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
class LinkChecker
2-
def self.check(record, log: true)
2+
attr_reader :log
3+
4+
def initialize(log: true)
5+
@log = log
6+
@cache = {}
7+
end
8+
9+
def check(collection)
10+
collection.find_each do |record|
11+
check_record(record)
12+
end
13+
end
14+
15+
def check_record(record)
316
[record, *record.external_resources].each do |item|
417
next if item.url.blank?
5-
code = bad_response(item.url, log: log)
18+
@cache[item.url] ||= bad_response(item.url) # Cache the result, there could be multiple resources linked to same URL
19+
code = @cache[item.url]
620
if code
721
puts " #{code} - #{item.class.name} #{item.id}: #{item.url}" if log
822
if item.link_monitor
@@ -18,9 +32,11 @@ def self.check(record, log: true)
1832
end
1933
end
2034

35+
private
36+
2137
# The fake return codes on an exception are so the LinkMonitor object has something
2238
# to store as "code" which might be tracked back to a particular problem.
23-
def self.bad_response(url, log: true)
39+
def bad_response(url)
2440
begin
2541
host = URI.parse(url).host rescue nil
2642
if @prev_host == host
@@ -48,7 +64,7 @@ def self.bad_response(url, log: true)
4864
end
4965

5066
# Gets a response code using a GET request, for the case where HEAD is not supported.
51-
def self.get_code(url, redirect_limit: 5, open_timeout: 5, read_timeout: 5, use_range: true)
67+
def get_code(url, redirect_limit: 5, open_timeout: 5, read_timeout: 5, use_range: true)
5268
raise StandardError, 'too many redirects' if redirect_limit <= 0
5369

5470
uri = URI(url)

lib/tasks/check_urls.rake

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,10 @@ end
2424

2525
def check_materials
2626
puts 'Checking material URLs'
27-
Material.find_each do |mat|
28-
LinkChecker.check(mat)
29-
end
27+
LinkChecker.new.check(Material)
3028
end
3129

3230
def check_events
3331
puts 'Checking event URLs'
34-
Event.find_each do |event|
35-
LinkChecker.check(event)
36-
end
32+
LinkChecker.new.check(Event)
3733
end

test/unit/link_checker_test.rb

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,29 @@
22

33
class LinkCheckerTest < ActiveSupport::TestCase
44

5+
setup do
6+
@link_checker = LinkChecker.new(log: false)
7+
end
8+
9+
test 'check collection' do
10+
event = events(:two)
11+
WebMock.stub_request(:head, event.url).to_return(status: 200)
12+
assert_nil event.link_monitor
13+
14+
assert_no_difference('LinkMonitor.count') do
15+
@link_checker.check(Event.where(id: event.id))
16+
end
17+
18+
assert_nil event.link_monitor
19+
end
20+
521
test 'check passing event url' do
622
event = events(:two)
723
WebMock.stub_request(:head, event.url).to_return(status: 200)
824
assert_nil event.link_monitor
925

1026
assert_no_difference('LinkMonitor.count') do
11-
LinkChecker.check(event, log: false)
27+
@link_checker.check_record(event)
1228
end
1329

1430
assert_nil event.link_monitor
@@ -20,7 +36,7 @@ class LinkCheckerTest < ActiveSupport::TestCase
2036
assert_nil event.link_monitor
2137

2238
assert_difference('LinkMonitor.count', 1) do
23-
LinkChecker.check(event, log: false)
39+
@link_checker.check_record(event)
2440
end
2541

2642
assert event.link_monitor
@@ -35,7 +51,7 @@ class LinkCheckerTest < ActiveSupport::TestCase
3551
assert_nil event.link_monitor
3652

3753
assert_no_difference('LinkMonitor.count') do
38-
LinkChecker.check(event, log: false)
54+
@link_checker.check_record(event)
3955
end
4056

4157
assert_nil event.link_monitor
@@ -49,7 +65,7 @@ class LinkCheckerTest < ActiveSupport::TestCase
4965
assert_nil event.link_monitor
5066

5167
assert_difference('LinkMonitor.count', 1) do
52-
LinkChecker.check(event, log: false)
68+
@link_checker.check_record(event)
5369
end
5470

5571
assert event.link_monitor
@@ -65,7 +81,7 @@ class LinkCheckerTest < ActiveSupport::TestCase
6581
assert_nil event.link_monitor
6682

6783
assert_difference('LinkMonitor.count', 1) do
68-
LinkChecker.check(event, log: false)
84+
@link_checker.check_record(event)
6985
end
7086

7187
assert event.link_monitor
@@ -81,7 +97,7 @@ class LinkCheckerTest < ActiveSupport::TestCase
8197
material = materials(:material_with_external_resource)
8298

8399
assert_difference('LinkMonitor.count', 2) do
84-
LinkChecker.check(material, log: false)
100+
@link_checker.check_record(material)
85101
end
86102
end
87103

0 commit comments

Comments
 (0)