warm_cloudfront 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []