heroku-readonly 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,61 @@
1
+ require 'rest_client'
2
+
3
+ module Heroku
4
+ class ReadOnly
5
+ def initialize(options={})
6
+ @enabled = false
7
+ @have_polled = false
8
+ @url = options[:url]
9
+ @time_between_retries = options[:time_between_retries] || 2
10
+ @write_cache = options[:write_cache]
11
+ @read_cache = options[:read_cache]
12
+ end
13
+
14
+ def check
15
+ Timeout.timeout(1) do
16
+ RestClient.get(@url) != 'ok'
17
+ end
18
+ rescue StandardError, Timeout::Error => e
19
+ true
20
+ end
21
+
22
+ def poll(attempt=1)
23
+ result = check
24
+ if (result == @enabled) || (attempt >= 3)
25
+ @have_polled = true
26
+ @enabled = result
27
+ write_to_cache
28
+ result
29
+ elsif attempt < 3
30
+ sleep(@time_between_retries)
31
+ poll(attempt+1)
32
+ end
33
+ end
34
+
35
+ def write_to_cache
36
+ if @write_cache
37
+ File.open(@write_cache, 'w') { |f| f.write(@enabled ? 'readonly' : 'ok') }
38
+ end
39
+ end
40
+
41
+ def read_from_cache
42
+ if !File.exists?(@read_cache)
43
+ true
44
+ elsif File.mtime(@read_cache) < Time.now - 60*5
45
+ true
46
+ else
47
+ File.read(@read_cache).strip != 'ok'
48
+ end
49
+ end
50
+
51
+ def enabled?
52
+ if @read_cache
53
+ read_from_cache
54
+ elsif !@have_polled
55
+ raise('never polled, no read_cache')
56
+ else
57
+ @enabled
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,72 @@
1
+ require "spec_helper"
2
+
3
+ describe Heroku::ReadOnly do
4
+ let(:url) { "http://foo" }
5
+ let(:readonly) { Heroku::ReadOnly.new(:url => url, :time_between_retries => 0) }
6
+
7
+ it "enabled if the response is a 200 'ok'" do
8
+ FakeWeb.register_uri(:get, url, :body => "ok")
9
+ readonly.poll.should be_false
10
+ readonly.enabled?.should be_false
11
+ end
12
+
13
+ it "enabled if the response has other text" do
14
+ FakeWeb.register_uri(:get, url, :body => "readonly")
15
+ readonly.poll.should be_true
16
+ readonly.enabled?.should be_true
17
+ end
18
+
19
+ it "enabled if the response has another status code" do
20
+ FakeWeb.register_uri(:get, url, :body => "ok", :status => 503)
21
+ readonly.poll.should be_true
22
+ readonly.enabled?.should be_true
23
+ end
24
+
25
+ it "only changes after fetching the same result 3 times" do
26
+ FakeWeb.register_uri(:get, url, :body => "ok")
27
+ readonly.poll.should be_false
28
+ FakeWeb.register_uri(:get, url, [
29
+ { :body => "readonly" },
30
+ { :body => "readonly" },
31
+ { :body => "ok" }
32
+ ])
33
+ readonly.poll.should be_false
34
+ readonly.enabled?.should be_false
35
+ end
36
+
37
+ context "caching" do
38
+ before do
39
+ FakeWeb.register_uri(:get, url, :body => "ok")
40
+ end
41
+
42
+ let(:cache) { "/tmp/read_only_spec" }
43
+ let(:readonly_write) { Heroku::ReadOnly.new(:url => url, :write_cache => cache, :time_between_retries => 0) }
44
+ let(:readonly_read) { Heroku::ReadOnly.new(:read_cache => cache) }
45
+
46
+ before(:each) do
47
+ File.unlink(cache) if File.exists?(cache)
48
+ end
49
+
50
+ it "enabled if the cache doesn't exist" do
51
+ readonly_read.enabled?.should be_true
52
+ end
53
+
54
+ it "enabled if the cache is old" do
55
+ readonly_write.poll.should be_false
56
+ old = Time.now - 60*60
57
+ File.utime(old, old, cache)
58
+ readonly_read.enabled?.should be_true
59
+ end
60
+
61
+ it "enabled if the cache has non-disabled text" do
62
+ FakeWeb.register_uri(:get, url, :body => "readonly")
63
+ readonly_write.poll.should be_true
64
+ readonly_read.enabled?.should be_true
65
+ end
66
+
67
+ it "not enabled if the cache has disabled text" do
68
+ readonly_write.poll.should be_false
69
+ readonly_read.enabled?.should be_false
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,15 @@
1
+ require "rspec/core"
2
+ require "rspec/expectations"
3
+
4
+ require "rubygems"
5
+ require "fakeweb"
6
+
7
+ $:.unshift "#{File.dirname(__FILE__)}/../lib/heroku"
8
+ require "readonly"
9
+
10
+ RSpec.configure do |c|
11
+ c.run_all_when_everything_filtered = true
12
+ c.filter_run :focused => true
13
+ c.alias_example_to :fit, :focused => true
14
+ c.color_enabled = true
15
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: heroku-readonly
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Heroku
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-15 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rake
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :development
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: rspec-core
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ~>
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 2
41
+ - 0
42
+ - 1
43
+ version: 2.0.1
44
+ type: :development
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec-expectations
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ segments:
54
+ - 2
55
+ - 0
56
+ - 1
57
+ version: 2.0.1
58
+ type: :development
59
+ version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ name: rspec-mocks
62
+ prerelease: false
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 2
69
+ - 0
70
+ - 1
71
+ version: 2.0.1
72
+ type: :development
73
+ version_requirements: *id004
74
+ - !ruby/object:Gem::Dependency
75
+ name: fakeweb
76
+ prerelease: false
77
+ requirement: &id005 !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ~>
80
+ - !ruby/object:Gem::Version
81
+ segments:
82
+ - 1
83
+ - 3
84
+ - 0
85
+ version: 1.3.0
86
+ type: :development
87
+ version_requirements: *id005
88
+ - !ruby/object:Gem::Dependency
89
+ name: rest-client
90
+ prerelease: false
91
+ requirement: &id006 !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ segments:
96
+ - 1
97
+ - 2
98
+ - 0
99
+ version: 1.2.0
100
+ type: :runtime
101
+ version_requirements: *id006
102
+ description:
103
+ email: support@heroku.com
104
+ executables: []
105
+
106
+ extensions: []
107
+
108
+ extra_rdoc_files: []
109
+
110
+ files:
111
+ - lib/heroku/readonly.rb
112
+ - spec/readonly_spec.rb
113
+ - spec/spec_helper.rb
114
+ has_rdoc: true
115
+ homepage: http://heroku.com/
116
+ licenses: []
117
+
118
+ post_install_message:
119
+ rdoc_options: []
120
+
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ segments:
128
+ - 0
129
+ version: "0"
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ segments:
135
+ - 0
136
+ version: "0"
137
+ requirements: []
138
+
139
+ rubyforge_project:
140
+ rubygems_version: 1.3.6
141
+ signing_key:
142
+ specification_version: 3
143
+ summary: Internal tool
144
+ test_files: []
145
+