hot_tub 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/.travis.yml +0 -2
- data/Gemfile +2 -1
- data/HISTORY.md +9 -0
- data/README.md +18 -13
- data/hot_tub.gemspec +2 -2
- data/lib/hot_tub/pool.rb +36 -24
- data/lib/hot_tub/session.rb +3 -3
- data/lib/hot_tub/version.rb +1 -1
- data/lib/hot_tub.rb +8 -0
- data/spec/pool_spec.rb +39 -9
- data/spec/session_spec.rb +4 -6
- data/spec/spec_helper.rb +13 -11
- metadata +9 -8
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -3,9 +3,10 @@ source "https://rubygems.org"
|
|
3
3
|
# Specify your gem's dependencies in http_hot_tub.gemspec
|
4
4
|
gemspec
|
5
5
|
gem 'rake'
|
6
|
-
|
6
|
+
|
7
7
|
group :development do
|
8
8
|
platform :ruby do
|
9
|
+
gem 'coveralls', :require => false
|
9
10
|
gem 'eventmachine'
|
10
11
|
gem 'em-http-request', '~> 1.0', :require => 'em-http'
|
11
12
|
gem 'em-synchrony', '~> 1.0', :require => ['em-synchrony', 'em-synchrony/em-http']
|
data/HISTORY.md
ADDED
data/README.md
CHANGED
@@ -6,18 +6,22 @@ A simple thread-safe connection pool and sessions gem. Out-of-the-box support fo
|
|
6
6
|
## Features
|
7
7
|
|
8
8
|
### HotTub::Pool
|
9
|
-
* Thread safe
|
9
|
+
* Thread safe / Fiber safe (with EM::HttpRequest + EM::Synchrony)
|
10
10
|
* Lazy clients/connections (created only when necessary)
|
11
11
|
* Can be used with any client library
|
12
12
|
* Support for cleaning dirty resources
|
13
13
|
* Set to expand pool under load that is eventually reaped back down to set size (never_block), can be disabled
|
14
|
-
* Attempts to close clients/connections
|
14
|
+
* Attempts to close clients/connections on shutdown
|
15
15
|
|
16
16
|
### HotTub::Session
|
17
|
-
* Thread safe
|
17
|
+
* Thread safe / Fiber safe (with EM::HttpRequest + EM::Synchrony)
|
18
18
|
* The same api as HotTub::Pool
|
19
19
|
* Can be used with HotTub::Pool or any client library
|
20
|
-
* Attempts to close clients/connections
|
20
|
+
* Attempts to close clients/connections on shutdown
|
21
|
+
|
22
|
+
## Requirements
|
23
|
+
HotTub is tested on MRI, JRUBY and Rubinius
|
24
|
+
* Ruby >= 1.9
|
21
25
|
|
22
26
|
## Installation
|
23
27
|
|
@@ -25,7 +29,7 @@ HotTub is available through [Rubygems](https://rubygems.org/gems/hot_tub) and ca
|
|
25
29
|
|
26
30
|
$ gem install hot_tub
|
27
31
|
|
28
|
-
|
32
|
+
### Rails setup
|
29
33
|
|
30
34
|
Add hot_tub to your gemfile:
|
31
35
|
|
@@ -49,19 +53,20 @@ Configure Logger by creating a hot_tub.rb initializer and adding the following:
|
|
49
53
|
require 'em-synchrony/em-http'
|
50
54
|
EM.synchrony do {
|
51
55
|
pool = HotTub::Pool.new(:size => 12) { EM::HttpRequest.new("http://somewebservice.com") }
|
56
|
+
# Make sure we set :keepalive as true
|
52
57
|
pool.run { |clnt| clnt.aget(:query => results, :keepalive => true) }
|
53
58
|
EM.stop
|
54
59
|
}
|
55
60
|
|
56
61
|
### Other
|
57
|
-
You can use any library you want with HotTub::Pool
|
58
|
-
|
62
|
+
You can use any library you want with HotTub::Pool. Close and clean can be defined at initialization
|
63
|
+
with lambdas, if they are not defined they are ignored.
|
59
64
|
|
60
65
|
url = "http://test12345.com"
|
61
66
|
pool = HotTub::Pool.new({:size => 10, :close => lambda {|clnt| clnt.close}}) { MyHttpLib.new }
|
62
|
-
pool.run { |clnt| clnt.get(
|
67
|
+
pool.run { |clnt| clnt.get(url,query).body }
|
63
68
|
|
64
|
-
## HotTub::Session
|
69
|
+
## HotTub::Session
|
65
70
|
HotTub::Sessions are a synchronized hash of clients/pools and are implemented similar HotTub::Pool.
|
66
71
|
For example, Excon is thread safe but you set a single url at the client level so sessions
|
67
72
|
are handy if you need to access multiple urls but would prefer a single object.
|
@@ -82,22 +87,22 @@ are handy if you need to access multiple urls but would prefer a single object.
|
|
82
87
|
end
|
83
88
|
|
84
89
|
### HotTub::Session with HotTub::Pool
|
85
|
-
Suppose you have a client that
|
90
|
+
Suppose you have a client that lacks pooling and session features you can use HotTub::Pool with HotTub::Sessions to get what you need.
|
86
91
|
|
87
92
|
require 'hot_tub'
|
88
93
|
require "em-synchrony"
|
89
94
|
require "em-synchrony/em-http"
|
90
95
|
|
91
|
-
# We
|
96
|
+
# We must tell HotTub::Session to use HotTub::Pool, pass any pool options in our
|
92
97
|
# options has, and our client block must accept the url argument
|
93
98
|
EM.synchrony do {
|
94
99
|
sessions = HotTub::Session.new(:with_pool => true, :size => 12) {|url| EM::HttpRequest.new(url, :inactivity_timeout => 0) }
|
95
100
|
|
96
101
|
sessions.run("http://somewebservice.com") do |clnt|
|
97
|
-
puts clnt.get(:query => results).response_header.status
|
102
|
+
puts clnt.get(:query => results, :keepalive => true).response_header.status
|
98
103
|
end
|
99
104
|
sessions.run("https://someotherwebservice.com") do |clnt|
|
100
|
-
puts clnt.get(:query => results).response_header.status
|
105
|
+
puts clnt.get(:query => results, :keepalive => true).response_header.status
|
101
106
|
end
|
102
107
|
EM.stop
|
103
108
|
}
|
data/hot_tub.gemspec
CHANGED
@@ -10,13 +10,13 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.homepage = "https://github.com/JoshMcKin/hot_tub"
|
11
11
|
s.license = "MIT"
|
12
12
|
s.summary = %q{A simple thread-safe http connection pooling gem.}
|
13
|
-
s.description = %q{A simple thread-safe http connection pooling gem.
|
13
|
+
s.description = %q{A simple thread-safe http connection pooling gem. Out-of-the-box support for Excon and EM-Http-Request}
|
14
14
|
|
15
15
|
s.rubyforge_project = "hot_tub"
|
16
16
|
|
17
17
|
s.add_development_dependency "rspec"
|
18
18
|
s.add_development_dependency "sinatra"
|
19
|
-
s.add_development_dependency "puma", "~> 2.0.0
|
19
|
+
s.add_development_dependency "puma", "~> 2.0.0"
|
20
20
|
s.add_development_dependency "excon"
|
21
21
|
|
22
22
|
s.files = `git ls-files`.split("\n")
|
data/lib/hot_tub/pool.rb
CHANGED
@@ -26,7 +26,6 @@ module HotTub
|
|
26
26
|
#
|
27
27
|
def initialize(options={},&client_block)
|
28
28
|
raise ArgumentError, 'a block that initializes a new client is required' unless block_given?
|
29
|
-
at_exit { close_all } # close connections at exit
|
30
29
|
@client_block = client_block
|
31
30
|
@options = {
|
32
31
|
:size => 5,
|
@@ -35,11 +34,13 @@ module HotTub
|
|
35
34
|
:close => nil, # => lambda {|clnt| clnt.close}
|
36
35
|
:clean => nil # => lambda {|clnt| clnt.clean}
|
37
36
|
}.merge(options)
|
38
|
-
@pool
|
39
|
-
@
|
40
|
-
@
|
41
|
-
@
|
42
|
-
@
|
37
|
+
@pool = [] # stores available connection
|
38
|
+
@register = [] # stores all connections at all times
|
39
|
+
@current_size = 0
|
40
|
+
@pool_mutex = (em_client? ? EM::Synchrony::Thread::Mutex.new : Mutex.new)
|
41
|
+
@last_activity = Time.now
|
42
|
+
@fetching_client = false
|
43
|
+
HotTub.hot_at_exit( em_client? ) {close_all}
|
43
44
|
end
|
44
45
|
|
45
46
|
# Hand off to client.run
|
@@ -56,8 +57,9 @@ module HotTub
|
|
56
57
|
|
57
58
|
# Calls close on all connections and reset the pools
|
58
59
|
def close_all
|
59
|
-
@
|
60
|
-
while clnt = @
|
60
|
+
@pool_mutex.synchronize do
|
61
|
+
while clnt = @register.pop
|
62
|
+
@pool.delete(clnt)
|
61
63
|
begin
|
62
64
|
close_client(clnt)
|
63
65
|
rescue => e
|
@@ -70,7 +72,7 @@ module HotTub
|
|
70
72
|
|
71
73
|
private
|
72
74
|
|
73
|
-
def
|
75
|
+
def em_client?
|
74
76
|
begin
|
75
77
|
(HotTub.em_synchrony? && @client_block.call.is_a?(EventMachine::HttpConnection))
|
76
78
|
rescue
|
@@ -97,10 +99,15 @@ module HotTub
|
|
97
99
|
raise BlockingTimeout, message
|
98
100
|
end
|
99
101
|
|
100
|
-
# Safely add client back to pool
|
102
|
+
# Safely add client back to pool, only if
|
103
|
+
# that clnt is registered
|
101
104
|
def push(clnt)
|
102
|
-
@
|
103
|
-
@
|
105
|
+
@pool_mutex.synchronize do
|
106
|
+
if @register.include?(clnt)
|
107
|
+
@pool << clnt
|
108
|
+
else
|
109
|
+
close_client(clnt)
|
110
|
+
end
|
104
111
|
end
|
105
112
|
nil # make sure never return the pool
|
106
113
|
end
|
@@ -108,11 +115,11 @@ module HotTub
|
|
108
115
|
# Safely pull client from pool, adding if allowed
|
109
116
|
def pop
|
110
117
|
@fetching_client = true # kill reap_pool
|
111
|
-
@
|
112
|
-
|
118
|
+
@pool_mutex.synchronize do
|
119
|
+
_add if add?
|
113
120
|
clnt = @pool.pop # get warm connection
|
114
121
|
if (clnt.nil? && @options[:never_block])
|
115
|
-
|
122
|
+
_add
|
116
123
|
clnt = @pool.pop
|
117
124
|
end
|
118
125
|
@fetching_client = false
|
@@ -133,27 +140,32 @@ module HotTub
|
|
133
140
|
(@pool.length == 0 && (@options[:size] > @current_size))
|
134
141
|
end
|
135
142
|
|
136
|
-
def add
|
137
|
-
@last_activity = Time.now
|
138
|
-
@current_size += 1
|
139
|
-
nc = new_client
|
140
|
-
HotTub.logger.info "Adding HotTub client: #{nc.class.name} to pool"
|
141
|
-
@pool << nc
|
142
|
-
end
|
143
|
-
|
144
143
|
def reap_pool?
|
145
144
|
(!@fetching_client && (@current_size > @options[:size]) && ((@last_activity + (600)) < Time.now))
|
146
145
|
end
|
147
146
|
|
148
147
|
# Remove extra connections from front of pool
|
149
148
|
def reap_pool
|
150
|
-
@
|
149
|
+
@pool_mutex.synchronize do
|
151
150
|
if reap_pool? && clnt = @pool.shift
|
151
|
+
@register.delete(clnt)
|
152
152
|
@current_size -= 1
|
153
153
|
close_client(clnt)
|
154
154
|
end
|
155
155
|
end
|
156
156
|
end
|
157
|
+
|
158
|
+
# _add is volatile; and may cause theading issues
|
159
|
+
# if called outside @pool_mutex.synchronize {}
|
160
|
+
def _add
|
161
|
+
@last_activity = Time.now
|
162
|
+
@current_size += 1
|
163
|
+
nc = new_client
|
164
|
+
HotTub.logger.info "Adding HotTub client: #{nc.class.name} to pool"
|
165
|
+
@register << nc
|
166
|
+
@pool << nc
|
167
|
+
end
|
168
|
+
# end volatile
|
157
169
|
end
|
158
170
|
class BlockingTimeout < StandardError;end
|
159
171
|
end
|
data/lib/hot_tub/session.rb
CHANGED
@@ -33,11 +33,11 @@ module HotTub
|
|
33
33
|
#
|
34
34
|
def initialize(options={},&client_block)
|
35
35
|
raise ArgumentError, "HotTub::Sessions requre a block on initialization that accepts a single argument" unless block_given?
|
36
|
-
at_exit { close_all } # close connections at exit
|
37
36
|
@options = options || {}
|
38
37
|
@client_block = client_block
|
39
38
|
@sessions = Hash.new
|
40
|
-
@mutex = (
|
39
|
+
@mutex = (em_client? ? EM::Synchrony::Thread::Mutex.new : Mutex.new)
|
40
|
+
HotTub.hot_at_exit( em_client? ) {close_all}
|
41
41
|
end
|
42
42
|
|
43
43
|
# Synchronizes initialization of our sessions
|
@@ -81,7 +81,7 @@ module HotTub
|
|
81
81
|
|
82
82
|
private
|
83
83
|
|
84
|
-
def
|
84
|
+
def em_client?
|
85
85
|
begin
|
86
86
|
(HotTub.em_synchrony? && @client_block.call("http://moc").is_a?(EventMachine::HttpConnection))
|
87
87
|
rescue
|
data/lib/hot_tub/version.rb
CHANGED
data/lib/hot_tub.rb
CHANGED
data/spec/pool_spec.rb
CHANGED
@@ -82,9 +82,18 @@ describe HotTub::Pool do
|
|
82
82
|
before(:each) do
|
83
83
|
@pool = HotTub::Pool.new(:size => 5) { MocClient.new }
|
84
84
|
5.times do
|
85
|
-
@pool.send(:
|
85
|
+
@pool.send(:_add)
|
86
86
|
end
|
87
87
|
end
|
88
|
+
|
89
|
+
it "should reset register" do
|
90
|
+
@pool.current_size.should eql(5)
|
91
|
+
@pool.instance_variable_get(:@register).length.should eql(5)
|
92
|
+
@pool.close_all
|
93
|
+
@pool.instance_variable_get(:@register).length.should eql(0)
|
94
|
+
@pool.current_size.should eql(0)
|
95
|
+
end
|
96
|
+
|
88
97
|
it "should reset pool" do
|
89
98
|
@pool.current_size.should eql(5)
|
90
99
|
@pool.instance_variable_get(:@pool).length.should eql(5)
|
@@ -126,10 +135,31 @@ describe HotTub::Pool do
|
|
126
135
|
end
|
127
136
|
end
|
128
137
|
|
129
|
-
describe '#
|
138
|
+
describe '#_add' do
|
130
139
|
it "should add connections for supplied url"do
|
131
|
-
@pool.
|
132
|
-
@pool.
|
140
|
+
pre_add_length = @pool.instance_variable_get(:@pool).length
|
141
|
+
@pool.send(:_add)
|
142
|
+
@pool.instance_variable_get(:@pool).length.should be > pre_add_length
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe '#push' do
|
147
|
+
context "connection is registered" do
|
148
|
+
it "should push connection back to pool" do
|
149
|
+
@pool.send(:_add)
|
150
|
+
clnt = @pool.instance_variable_get(:@pool).pop
|
151
|
+
@pool.send(:push,clnt)
|
152
|
+
@pool.instance_variable_get(:@pool).include?(clnt).should be_true
|
153
|
+
end
|
154
|
+
end
|
155
|
+
context "connection is not registered" do
|
156
|
+
it "should not push connection back to pool" do
|
157
|
+
@pool.send(:_add)
|
158
|
+
clnt = @pool.instance_variable_get(:@pool).pop
|
159
|
+
@pool.instance_variable_get(:@register).delete(clnt)
|
160
|
+
@pool.send(:push,clnt)
|
161
|
+
@pool.instance_variable_get(:@pool).include?(clnt).should be_false
|
162
|
+
end
|
133
163
|
end
|
134
164
|
end
|
135
165
|
end
|
@@ -260,7 +290,7 @@ describe HotTub::Pool do
|
|
260
290
|
end
|
261
291
|
|
262
292
|
unless HotTub.jruby?
|
263
|
-
describe "
|
293
|
+
describe "em_client?" do
|
264
294
|
context 'EM::HttpRequest as client' do
|
265
295
|
before(:each) do
|
266
296
|
@pool = HotTub::Pool.new { EM::HttpRequest.new(HotTub::Server.url) }
|
@@ -268,20 +298,20 @@ describe HotTub::Pool do
|
|
268
298
|
context "EM::Synchrony is present" do
|
269
299
|
it "should be true" do
|
270
300
|
HotTub.stub(:em_synchrony?).and_return(true)
|
271
|
-
@pool.send(:
|
301
|
+
@pool.send(:em_client?).should be_true
|
272
302
|
end
|
273
303
|
end
|
274
304
|
context "EM::Synchrony is not present" do
|
275
305
|
it "should be false" do
|
276
306
|
HotTub.stub(:em_synchrony?).and_return(false)
|
277
|
-
@pool.send(:
|
307
|
+
@pool.send(:em_client?).should be_false
|
278
308
|
end
|
279
309
|
end
|
280
310
|
end
|
281
311
|
context 'client is not EM::HttpRequest' do
|
282
312
|
it "should be false" do
|
283
313
|
pool = HotTub::Pool.new {|url| MocClient.new}
|
284
|
-
pool.send(:
|
314
|
+
pool.send(:em_client?).should be_false
|
285
315
|
end
|
286
316
|
end
|
287
317
|
end
|
@@ -294,7 +324,7 @@ describe HotTub::Pool do
|
|
294
324
|
it "should work" do
|
295
325
|
EM.synchrony do
|
296
326
|
status = []
|
297
|
-
c = HotTub::Pool.new
|
327
|
+
c = HotTub::Pool.new {EM::HttpRequest.new(@url)}
|
298
328
|
c.run { |conn| status << conn.head(:keepalive => true).response_header.status}
|
299
329
|
c.run { |conn| status << conn.ahead(:keepalive => true).response_header.status}
|
300
330
|
c.run { |conn| status << conn.head(:keepalive => true).response_header.status}
|
data/spec/session_spec.rb
CHANGED
@@ -120,7 +120,6 @@ describe HotTub::Session do
|
|
120
120
|
failed = false
|
121
121
|
start_time = Time.now
|
122
122
|
stop_time = nil
|
123
|
-
mutex = Mutex.new
|
124
123
|
threads = []
|
125
124
|
lambda {
|
126
125
|
10.times.each do
|
@@ -146,7 +145,7 @@ describe HotTub::Session do
|
|
146
145
|
|
147
146
|
unless HotTub.jruby?
|
148
147
|
|
149
|
-
describe "
|
148
|
+
describe "em_client?" do
|
150
149
|
|
151
150
|
context 'EM::HttpRequest as client' do
|
152
151
|
before(:each) do
|
@@ -155,20 +154,20 @@ describe HotTub::Session do
|
|
155
154
|
context "EM::Synchrony is present" do
|
156
155
|
it "should be true" do
|
157
156
|
HotTub.stub(:em_synchrony?).and_return(true)
|
158
|
-
@session.send(:
|
157
|
+
@session.send(:em_client?).should be_true
|
159
158
|
end
|
160
159
|
end
|
161
160
|
context "EM::Synchrony is not present" do
|
162
161
|
it "should be false" do
|
163
162
|
HotTub.stub(:em_synchrony?).and_return(false)
|
164
|
-
@session.send(:
|
163
|
+
@session.send(:em_client?).should be_false
|
165
164
|
end
|
166
165
|
end
|
167
166
|
end
|
168
167
|
context 'client is not EM::HttpRequest' do
|
169
168
|
it "should be false" do
|
170
169
|
session = HotTub::Session.new {|url| MocClient.new}
|
171
|
-
session.send(:
|
170
|
+
session.send(:em_client?).should be_false
|
172
171
|
end
|
173
172
|
end
|
174
173
|
end
|
@@ -205,7 +204,6 @@ describe HotTub::Session do
|
|
205
204
|
sessions.instance_variable_get(:@sessions).keys.length.should eql(1)
|
206
205
|
(sessions.sessions(@url).instance_variable_get(:@pool).length >= 5).should be_true #make sure work got done
|
207
206
|
failed.should be_false # Make sure our requests worked
|
208
|
-
sessions.close_all
|
209
207
|
EM.stop
|
210
208
|
end
|
211
209
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -6,8 +6,10 @@ require 'excon'
|
|
6
6
|
require 'helpers/moc_client'
|
7
7
|
require 'helpers/server'
|
8
8
|
require 'net/https'
|
9
|
-
|
10
|
-
|
9
|
+
unless HotTub.jruby? || HotTub.rbx?
|
10
|
+
require 'coveralls'
|
11
|
+
Coveralls.wear!
|
12
|
+
end
|
11
13
|
|
12
14
|
# Requires supporting files with custom matchers and macros, etc,
|
13
15
|
# in ./support/ and its subdirectories.
|
@@ -15,12 +17,12 @@ Coveralls.wear! unless HotTub.jruby? || HotTub.rbx?
|
|
15
17
|
HotTub.logger.level = Logger::ERROR
|
16
18
|
|
17
19
|
RSpec.configure do |config|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
20
|
+
config.before(:suite) do
|
21
|
+
HotTub::Server.run
|
22
|
+
HotTub::Server2.run
|
23
|
+
end
|
24
|
+
config.after(:suite) do
|
25
|
+
HotTub::Server.teardown
|
26
|
+
HotTub::Server2.teardown
|
27
|
+
end
|
28
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hot_tub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-05-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -50,7 +50,7 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: 2.0.0
|
53
|
+
version: 2.0.0
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -58,7 +58,7 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 2.0.0
|
61
|
+
version: 2.0.0
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
63
|
name: excon
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,8 +75,8 @@ dependencies:
|
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
|
-
description: A simple thread-safe http connection pooling gem.
|
79
|
-
|
78
|
+
description: A simple thread-safe http connection pooling gem. Out-of-the-box support
|
79
|
+
for Excon and EM-Http-Request
|
80
80
|
email:
|
81
81
|
- joshmckin@gmail.com
|
82
82
|
executables: []
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- .rspec
|
88
88
|
- .travis.yml
|
89
89
|
- Gemfile
|
90
|
+
- HISTORY.md
|
90
91
|
- LICENSE.txt
|
91
92
|
- README.md
|
92
93
|
- Rakefile
|
@@ -116,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
117
|
version: '0'
|
117
118
|
segments:
|
118
119
|
- 0
|
119
|
-
hash: -
|
120
|
+
hash: -3131859420697003965
|
120
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
122
|
none: false
|
122
123
|
requirements:
|
@@ -125,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
126
|
version: '0'
|
126
127
|
segments:
|
127
128
|
- 0
|
128
|
-
hash: -
|
129
|
+
hash: -3131859420697003965
|
129
130
|
requirements: []
|
130
131
|
rubyforge_project: hot_tub
|
131
132
|
rubygems_version: 1.8.25
|