hot_tub 0.5.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module HotTub
2
- VERSION = "0.5.3"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -6,19 +6,39 @@ class MocPool < MocMixinPool
6
6
  attr_accessor :reaped, :lets_reap
7
7
 
8
8
  def initialize
9
- @reaped = false
10
- @lets_reap = false
9
+ @reaped = false
10
+ @lets_reap = false
11
11
  end
12
12
 
13
13
  def reap!
14
- @reaped = true if @lets_reap
14
+ @reaped = true if @lets_reap
15
+ @lets_reap = false
15
16
  end
16
17
  end
17
18
 
18
19
  class MocReaperPool < MocPool
20
+ attr_accessor :mx, :cv, :reaped
19
21
  def initialize
20
- super
21
- @reap_timeout = 1
22
+ super
23
+ @reap_timeout = 0.01
24
+
25
+ @mx = Mutex.new
26
+ @cv = ConditionVariable.new
27
+ @reaped = false
28
+
22
29
  @reaper = HotTub::Reaper.spawn(self)
23
30
  end
24
- end
31
+
32
+ def wait_for_reap
33
+ @mx.synchronize do
34
+ @cv.wait(@mx)
35
+ end
36
+ end
37
+
38
+ def reap!
39
+ @mx.synchronize do
40
+ @reaped = true
41
+ @cv.signal
42
+ end
43
+ end
44
+ end
@@ -1,10 +1,9 @@
1
1
  require 'spec_helper'
2
-
3
2
  describe HotTub do
4
3
 
5
4
  context "blocking (size equals max_size)" do
6
5
  let(:pool) do
7
- HotTub.new(:size => 4, :max_size => 4) {
6
+ HotTub::Pool.new(:size => 4, :max_size => 4) {
8
7
  Excon.new(HotTub::Server.url, :thread_safe_sockets => false)
9
8
  }
10
9
  end
@@ -33,7 +32,7 @@ describe HotTub do
33
32
 
34
33
  context "with larger max" do
35
34
  let(:pool) do
36
- HotTub.new(:size => 4, :max_size => 8) {
35
+ HotTub::Pool.new(:size => 4, :max_size => 8) {
37
36
  Excon.new(HotTub::Server.url, :thread_safe_sockets => false)
38
37
  }
39
38
  end
@@ -52,7 +51,7 @@ describe HotTub do
52
51
 
53
52
  it "should reap" do
54
53
  pool.reap!
55
- expect(pool.current_size).to be <= 4
54
+ expect(pool.current_size).to be <= 4
56
55
  end
57
56
 
58
57
  it "should work" do
@@ -64,7 +63,7 @@ describe HotTub do
64
63
 
65
64
  context "sized without max" do
66
65
  let(:pool) do
67
- HotTub.new(:size => 4) {
66
+ HotTub::Pool.new(:size => 4) {
68
67
  Excon.new(HotTub::Server.url, :thread_safe_sockets => false)
69
68
  }
70
69
  end
@@ -90,34 +89,6 @@ describe HotTub do
90
89
  expect(results.uniq).to eql([200])
91
90
  end
92
91
  end
93
-
94
- context "shutdown with slow client" do
95
- let(:pool) do
96
- HotTub.new(:size => 1) {
97
- Excon.new(HotTub::Server.slow_url, :thread_safe_sockets => false, :read_timeout => 2)
98
- }
99
- end
100
-
101
- it "should work" do
102
- begin
103
- th = Thread.new do
104
- uri = URI.parse(HotTub::Server.slow_url)
105
- pool.run do |connection|
106
- connection.get(:path => uri.path).status
107
- end
108
- end
109
- sleep(0.01)
110
- pool.shutdown!
111
- th.join
112
- rescue => e
113
- puts e.message
114
- end
115
-
116
- expect(pool.shutdown).to eql(true)
117
- expect(pool.current_size).to eql(0)
118
- end
119
- end
120
-
121
92
  end
122
93
 
123
94
  def excon_thread_work(pool,thread_count=0, threads=[])
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe HotTub do
4
4
  context "blocking (size equals max_size)" do
5
5
  let(:pool) do
6
- HotTub.new(:size => 4, :max_size => 4) {
6
+ HotTub::Pool.new(:size => 4, :max_size => 4) {
7
7
  uri = URI.parse(HotTub::Server.url)
8
8
  http = Net::HTTP.new(uri.host, uri.port)
9
9
  http.use_ssl = false
@@ -36,7 +36,7 @@ describe HotTub do
36
36
 
37
37
  context "with larger max" do
38
38
  let(:pool) do
39
- HotTub.new(:size => 4, :max_size => 8) {
39
+ HotTub::Pool.new(:size => 4, :max_size => 8) {
40
40
  uri = URI.parse(HotTub::Server.url)
41
41
  http = Net::HTTP.new(uri.host, uri.port)
42
42
  http.use_ssl = false
@@ -64,7 +64,7 @@ describe HotTub do
64
64
 
65
65
  context "sized without max" do
66
66
  let(:pool) do
67
- HotTub.new(:size => 4) {
67
+ HotTub::Pool.new(:size => 4) {
68
68
  uri = URI.parse(HotTub::Server.url)
69
69
  http = Net::HTTP.new(uri.host, uri.port)
70
70
  http.use_ssl = false
@@ -21,7 +21,7 @@ describe HotTub::Pool do
21
21
  end
22
22
 
23
23
  it "should have a HotTub::Reaper" do
24
- expect(pool.reaper).to be_a(Thread)
24
+ expect(pool.reaper).to be_a(HotTub::Reaper)
25
25
  end
26
26
  end
27
27
 
@@ -210,14 +210,12 @@ describe HotTub::Pool do
210
210
  context 'thread safety' do
211
211
  it "should grow" do
212
212
  pool = HotTub::Pool.new({:size => 4}) { MocClient.new }
213
- failed = false
214
213
  threads = []
215
214
  20.times.each do
216
215
  threads << Thread.new do
217
- pool.run{|connection| connection.get }
216
+ pool.run { |connection| connection.get }
218
217
  end
219
218
  end
220
- sleep(0.01)
221
219
  threads.each do |t|
222
220
  t.join
223
221
  end
@@ -1,27 +1,21 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe HotTub::Reaper do
4
-
5
- let(:pool) { MocReaperPool.new }
6
- let(:reaper) { pool.reaper }
4
+
5
+ let(:pool) { MocReaperPool.new }
6
+ let(:reaper) { pool.reaper }
7
7
 
8
8
  it "should be a HotTub::Reaper Thread" do
9
- expect(reaper).to be_a(Thread)
9
+ expect(reaper.thread).to be_a(Thread)
10
10
  end
11
11
 
12
12
  it "should reap!" do
13
- expect(pool.reaped).to eql(false)
14
- pool.lets_reap = true
15
- reaper.wakeup
16
- sleep(0.01)
13
+ pool.wait_for_reap
17
14
  expect(pool.reaped).to eql(true)
18
15
  end
19
16
 
20
- it "should sleep after reap!" do
21
- expect(pool.reaped).to eql(false)
22
- pool.lets_reap = true
23
- reaper.wakeup
24
- sleep(0.01)
25
- expect(reaper.status).to eql('sleep')
17
+ it "should still be alive" do
18
+ pool.wait_for_reap
19
+ expect(reaper).to be_alive
26
20
  end
27
21
  end
@@ -2,23 +2,53 @@ require 'spec_helper'
2
2
  require 'hot_tub/sessions'
3
3
  require 'uri'
4
4
  require 'time'
5
- describe HotTub::Sessions do
6
-
7
5
 
8
- context 'initialized with a block' do
6
+ describe HotTub::Sessions do
9
7
 
8
+ describe '#stage' do
10
9
  let(:key) { "https://www.somewebsite.com" }
11
10
 
12
11
  let(:sessions) { HotTub::Sessions.new }
13
12
 
14
- describe '#sessions' do
15
- context 'HotTub::Pool as client' do
16
- it "should add a new client for the key" do
17
- sessions = HotTub::Sessions.new
18
- sessions.get_or_set(key) { MocClient.new }
19
- sns = sessions.instance_variable_get(:@_sessions)
20
- expect(sns.size).to eql(1)
21
- sns.each_value {|v| expect(v).to be_a( HotTub::Pool)}
13
+ it { expect(sessions.stage(key) { MocClient.new }).to be_nil }
14
+
15
+ it "should lazy load pool" do
16
+ sessions.stage(key) { MocClient.new }
17
+ expect(sessions.fetch(key)).to be_a(HotTub::Pool)
18
+ end
19
+ end
20
+
21
+
22
+ describe '#get_or_set' do
23
+
24
+ context "with &default_client" do
25
+ let(:key) { "https://www.somewebsite.com" }
26
+
27
+ let(:sessions) do
28
+ sns = HotTub::Sessions.new #{ MocClient.new }
29
+ sns.default_client = lambda { |url| MocClient.new(url) }
30
+ sns
31
+ end
32
+
33
+ it "should add a new pool for the key" do
34
+ pool = sessions.get_or_set(key)
35
+ expect(pool).to be_a(HotTub::Pool)
36
+ pool.run do |clnt|
37
+ expect(clnt).to be_a(MocClient)
38
+ end
39
+ end
40
+ end
41
+
42
+ context "with &client_block" do
43
+ let(:key) { "https://www.somewebsite.com" }
44
+
45
+ let(:sessions) { HotTub::Sessions.new }
46
+
47
+ it "should add a new client for the key" do
48
+ pool = sessions.get_or_set(key) { MocClient.new }
49
+ expect(pool).to be_a(HotTub::Pool)
50
+ pool.run do |clnt|
51
+ expect(clnt).to be_a(MocClient)
22
52
  end
23
53
  end
24
54
  end
@@ -31,14 +61,14 @@ describe HotTub::Sessions do
31
61
 
32
62
  it "should start reaper after add" do
33
63
  expect(sessions.reaper).to be_nil
34
- sessions.get_or_set("https://www.somewebsite.com") { MocClient.new }
35
- expect(sessions.reaper).to be_a(Thread)
64
+ sessions.get_or_set("https://www.somewebsite.com") { MocClient.new }
65
+ expect(sessions.reaper).to be_a(HotTub::Reaper)
36
66
  end
37
67
 
38
68
  it "should disable pool based reaper" do
39
- sessions.get_or_set("https://www.somewebsite.com") { MocClient.new }
40
- sessions.get_or_set("https://www.someOtherwebsite.com") { MocClient.new }
41
- sessions.get_or_set("https://www.someOtherwebsiteToo.com") { MocClient.new }
69
+ sessions.get_or_set("https://www.somewebsite.com") { MocClient.new }
70
+ sessions.get_or_set("https://www.someOtherwebsite.com") { MocClient.new }
71
+ sessions.get_or_set("https://www.someOtherwebsiteToo.com") { MocClient.new }
42
72
  session = sessions.instance_variable_get(:@_sessions)
43
73
  session.each_value {|v| expect(v.reaper).to eql(false)}
44
74
  end
data/spec/hot_tub_spec.rb CHANGED
@@ -4,7 +4,7 @@ describe HotTub do
4
4
  context "helpers" do
5
5
  describe '#new' do
6
6
  it "should return a HotTub::Pool" do
7
- expect(HotTub.new { |url| MocClient.new(url) }).to be_a(HotTub::Pool)
7
+ expect(HotTub::Pool.new { |url| MocClient.new(url) }).to be_a(HotTub::Pool)
8
8
  end
9
9
  end
10
10
 
data/spec/spec_helper.rb CHANGED
@@ -8,6 +8,11 @@ require 'helpers/moc_client'
8
8
  require 'helpers/server'
9
9
  require 'net/https'
10
10
 
11
+ begin
12
+ require 'byebug'
13
+ rescue LoadError
14
+ end
15
+
11
16
  unless HotTub.jruby? || HotTub.rbx?
12
17
  require 'coveralls'
13
18
  Coveralls.wear!
metadata CHANGED
@@ -1,95 +1,95 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hot_tub
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Mckinney
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-06 00:00:00.000000000 Z
11
+ date: 2015-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- version_requirements: !ruby/object:Gem::Requirement
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
17
  - - ">="
17
18
  - !ruby/object:Gem::Version
18
19
  version: '0'
19
- name: rspec
20
20
  type: :development
21
21
  prerelease: false
22
- requirement: !ruby/object:Gem::Requirement
22
+ version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- version_requirements: !ruby/object:Gem::Requirement
28
+ name: rspec-autotest
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
31
  - - ">="
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
- name: rspec-autotest
34
34
  type: :development
35
35
  prerelease: false
36
- requirement: !ruby/object:Gem::Requirement
36
+ version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- version_requirements: !ruby/object:Gem::Requirement
42
+ name: autotest
43
+ requirement: !ruby/object:Gem::Requirement
43
44
  requirements:
44
45
  - - ">="
45
46
  - !ruby/object:Gem::Version
46
47
  version: '0'
47
- name: autotest
48
48
  type: :development
49
49
  prerelease: false
50
- requirement: !ruby/object:Gem::Requirement
50
+ version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- version_requirements: !ruby/object:Gem::Requirement
56
+ name: sinatra
57
+ requirement: !ruby/object:Gem::Requirement
57
58
  requirements:
58
59
  - - ">="
59
60
  - !ruby/object:Gem::Version
60
61
  version: '0'
61
- name: sinatra
62
62
  type: :development
63
63
  prerelease: false
64
- requirement: !ruby/object:Gem::Requirement
64
+ version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- version_requirements: !ruby/object:Gem::Requirement
70
+ name: puma
71
+ requirement: !ruby/object:Gem::Requirement
71
72
  requirements:
72
73
  - - "~>"
73
74
  - !ruby/object:Gem::Version
74
75
  version: '2.0'
75
- name: puma
76
76
  type: :development
77
77
  prerelease: false
78
- requirement: !ruby/object:Gem::Requirement
78
+ version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '2.0'
83
83
  - !ruby/object:Gem::Dependency
84
- version_requirements: !ruby/object:Gem::Requirement
84
+ name: excon
85
+ requirement: !ruby/object:Gem::Requirement
85
86
  requirements:
86
87
  - - ">="
87
88
  - !ruby/object:Gem::Version
88
89
  version: '0'
89
- name: excon
90
90
  type: :development
91
91
  prerelease: false
92
- requirement: !ruby/object:Gem::Requirement
92
+ version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
@@ -110,6 +110,8 @@ files:
110
110
  - README.md
111
111
  - Rakefile
112
112
  - benchmarks/block_passing.rb
113
+ - benchmarks/compare_concurrent.rb
114
+ - benchmarks/compare_serial.rb
113
115
  - benchmarks/hot_tub.rb
114
116
  - hot_tub.gemspec
115
117
  - lib/hot_tub.rb