hot_tub 0.5.3 → 1.0.0

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.
@@ -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