warm_cloudfront 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: aab609eddef5c742047cefffa1f054b76066c428
4
+ data.tar.gz: 6537e133ec3fa57f10f49d4d3fe566ea82d0df43
5
+ SHA512:
6
+ metadata.gz: 7c4304b1a134ff217c31e4498d3af5cb078b5bc53b493d7269dfe6078f585c7853aa3a0f4177cc82a4b5dbf731712a119614c2c5c13c3ccacce747cc9d049d59
7
+ data.tar.gz: 9a931ea036f01f1c6c442a599b5cf1113336f41a5c7ebb5e5e4dcb3a188765f7560bf05780ad3d4c2f4e0bfa43edf23702bee95d76983ce75afb64c07884757c
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/warm_cloudfront'
4
+
5
+ if ARGV.length < 2
6
+ puts 'Usage: warm_cloudfront {cloudfront_subdomain} {path1} [{path2}] ...'
7
+ exit -1
8
+ end
9
+
10
+ cloudfront_id = ARGV.slice! 0
11
+ paths = ARGV.to_a
12
+
13
+ WarmCloudfront.new(cloudfront_id).warm(paths)
@@ -0,0 +1,87 @@
1
+ require 'typhoeus'
2
+ require 'yaml'
3
+ require 'ruby-progressbar'
4
+
5
+ class WarmCloudfront
6
+ CLOUDFRONT_EDGES = YAML.load_file(File.join(__dir__, 'warm_cloudfront/edge.yml'))[:cloudfront]
7
+
8
+ def initialize(cloudfront_id)
9
+ @domains = CLOUDFRONT_EDGES.map do |edge|
10
+ "#{cloudfront_id}.#{edge.downcase}.cloudfront.net"
11
+ end
12
+ @host = "#{cloudfront_id}.cloudfront.net"
13
+ @warmed = 0
14
+ @errors = 0
15
+ end
16
+
17
+ def warm(paths)
18
+ hydra = Typhoeus::Hydra.new
19
+ paths.each do |path|
20
+ path = "/#{path}" if path[0] != '/'
21
+ @domains.each do |domain|
22
+ req = request("#{domain}#{path}")
23
+ hydra.queue req
24
+ end
25
+ end
26
+
27
+ total = hydra.queued_requests.length
28
+ @progress_bar = ProgressBar.create(
29
+ title: 'Warming',
30
+ total: total,
31
+ format: '%t %c/%C|%b>>%i| %p%%'
32
+ )
33
+ hydra.run
34
+ log.info "Warmed #{total} objects: #{@warmed} cache misses, #{total-@warmed-@errors} cache hits#{", #{@errors} errors" if @errors.nonzero?}."
35
+ end
36
+
37
+ def request(url)
38
+ request = Typhoeus::Request.new(
39
+ url,
40
+ # CF separately caches GET and HEAD responses, so we must send GET requests
41
+ headers: {
42
+ Host: @host,
43
+ 'Accept-Encoding' => 'gzip' # CF separately caches gzip requests from non-gzip requests
44
+ }
45
+ )
46
+ request.on_headers do |response|
47
+ @progress_bar.increment
48
+ if response.code == 200
49
+ @warmed += 1 if response.headers['X-Cache'] == 'Miss from cloudfront'
50
+ elsif response.timed_out?
51
+ log.warn "Timeout from #{url}"
52
+ @errors += 1
53
+ elsif response.code == 0
54
+ # Could not get an http response, something's wrong.
55
+ log.warn "No response from #{url}: #{response.return_message}"
56
+ @errors += 1
57
+ else
58
+ # Received a non-successful http response.
59
+ log.warn "HTTP request failed from #{url}: #{response.code.to_s}"
60
+ @errors += 1
61
+ end
62
+ end
63
+ request.on_body do |_|
64
+ # We don't need to download the full body, just send the GET request
65
+ :abort
66
+ end
67
+ request
68
+ end
69
+
70
+ # Simple default logger implementation
71
+ class << self
72
+ attr_writer :log
73
+ def log
74
+ class_variable_defined?(:@@log)?
75
+ class_variable_get(:@@log):
76
+ (self.log = Logger.new(STDOUT).tap do |l|
77
+ l.level = Logger::INFO
78
+ l.formatter = proc do |severity, _, _, msg|
79
+ "#{severity != 'INFO' ? "#{severity}: " : ''}#{msg}\n"
80
+ end
81
+ end)
82
+ end
83
+ end
84
+ def log
85
+ self.class.log
86
+ end
87
+ end
@@ -0,0 +1,123 @@
1
+ # List of Amazon CloudFront edge server codes
2
+ # Last updated: 6/28/2015
3
+ #
4
+ # Compiled from these sources:
5
+ # - http://blog.domenech.org/2013/10/amazon-web-services-cloudfront-edgelocation-codes.html
6
+ # - https://forums.aws.amazon.com/thread.jspa?threadID=86653&tstart=0&messageID=318072#318072
7
+ # - Reference list of locations from http://aws.amazon.com/cloudfront/details/
8
+
9
+ # Discrepancies:
10
+ # - Palo Alto, CA (SFO4)
11
+ # - Milan, Italy (MXP4)
12
+ ---
13
+ :cloudfront:
14
+ # United States:
15
+
16
+ # Atlanta, GA
17
+ - ATL50
18
+ # Ashburn, VA (3)
19
+ - IAD2
20
+ - IAD12
21
+ - IAD53
22
+ # Dallas/Fort Worth, TX (2)
23
+ - DFW3
24
+ - DFW50
25
+ # Hayward, CA
26
+ - SFO9
27
+ # Jacksonville, FL
28
+ - JAX1
29
+ # Los Angeles, CA (2)
30
+ - LAX1
31
+ - LAX3
32
+ # Miami, FL
33
+ #- MIA3 (retired)
34
+ - MIA50
35
+ # New York, NY (3)
36
+ - JFK1
37
+ - JFK5
38
+ - JFK6
39
+ # Newark, NJ
40
+ - EWR2
41
+ # Palo Alto, CA
42
+ #- SFO4 (retired)
43
+ - SFO20
44
+ # San Jose, CA
45
+ - SFO5
46
+ # Seattle, WA
47
+ #- SEA4 (retired)
48
+ - SEA50
49
+ # South Bend, IN
50
+ - IND6
51
+ # St. Louis, MO
52
+ - STL2
53
+
54
+ # Europe:
55
+
56
+ # Amsterdam, The Netherlands (2)
57
+ - AMS1
58
+ - AMS50
59
+ # Dublin, Ireland
60
+ - DUB2
61
+ # Frankfurt, Germany (3)
62
+ - FRA2
63
+ - FRA6
64
+ - FRA50
65
+ # London, England (3)
66
+ - LHR3
67
+ - LHR5
68
+ - LHR50
69
+ # Madrid, Spain
70
+ - MAD50
71
+ # Marseille, France
72
+ - MRS50
73
+ # Milan, Italy
74
+ #- MXP4 (down/cannot resolve host?)
75
+ # Paris, France (2)
76
+ #- CDG3 (retired)
77
+ - CDG50
78
+ - CDG51
79
+ # Stockholm, Sweden
80
+ - ARN1
81
+ # Warsaw, Poland
82
+ - WAW50
83
+
84
+ # Asia:
85
+
86
+ # Chennai, India
87
+ - MAA3
88
+ # Hong Kong (2)
89
+ #- HKG1 (retired)
90
+ - HKG50
91
+ - HKG51
92
+ # Mumbai, India
93
+ - BOM2
94
+ # Manila, the Philippines
95
+ - MNL50
96
+ # Osaka, Japan
97
+ #- NRT54 (retired)
98
+ - NRT12
99
+ # Seoul, Korea (2)
100
+ - ICN50
101
+ # Singapore (2)
102
+ - SIN2
103
+ - SIN3
104
+ # Taipei, Taiwan
105
+ - TPE50
106
+ # Tokyo, Japan (2)
107
+ #- NRT4 (retired)
108
+ - NRT52
109
+ - NRT53
110
+
111
+ # Australia:
112
+
113
+ # Melbourne, Australia
114
+ - MEL50
115
+ # Sydney, Australia
116
+ - SYD1
117
+
118
+ # South America:
119
+
120
+ # São Paulo, Brazil
121
+ - GRU1
122
+ # Rio de Janeiro, Brazil
123
+ - GIG50
@@ -0,0 +1,3 @@
1
+ module WarmCloudfront
2
+ VERSION = '0.0.1'
3
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: warm_cloudfront
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Will Jordan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: typhoeus
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ruby-progressbar
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description:
70
+ email:
71
+ executables:
72
+ - warm_cloudfront
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - bin/warm_cloudfront
77
+ - lib/warm_cloudfront.rb
78
+ - lib/warm_cloudfront/edge.yml
79
+ - lib/warm_cloudfront/version.rb
80
+ homepage:
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.4.5
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Warms up your CloudFront cache
104
+ test_files: []