future-resource 1.0.0 → 1.1.0

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: fada9a3ae4b808ac35ff57eeb6457279379f107a
4
+ data.tar.gz: 743d6407f87f5cb6cc457d9a71e294e0ac4ae328
5
+ SHA512:
6
+ metadata.gz: a07de1b6a90bc493d5a266ace5216c77032a5a9b76073e262a104b01b689bdf6b6fb772018c997fa0c38c60982d1484aa387a3ac361933698e634074ecff0cec
7
+ data.tar.gz: 9575c571273ccc28f9fa6e5508c5ab5128825911c4c9e1ce64be83553d4252fb1aed1d6097079751086dadb162f4f973c8873ed9c5457f4576256dcd13a42033
@@ -2,8 +2,8 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.2
4
4
  - 1.9.3
5
- - jruby-19mode # JRuby in 1.9 mode
6
- - rbx-19mode # currently in active development, may or may not work for your project
5
+ - rbx-19mode
6
+ - jruby-19mode
7
7
  - ruby-head
8
8
  notifications:
9
9
  irc: "irc.freenode.org#adhearsion"
@@ -1,5 +1,9 @@
1
1
  # develop
2
2
 
3
+ # 1.1.0 - 2013-07-05
4
+ * Feature: Allow setting an alternative condition to permit use of Celluloid::Condition in place of ConditionVariable
5
+ * Feature: Allow termination of resources, which raises an exception on reads
6
+
3
7
  # 1.0.0 - 2012-03-13
4
8
  * Feature: Better testing and documentation
5
9
 
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in future-resource.gemspec
4
3
  gemspec
data/Guardfile CHANGED
@@ -1,4 +1,4 @@
1
- guard 'rspec', :version => 2, :cli => '--format documentation' do
1
+ guard 'rspec', :cli => '--format documentation' do
2
2
  watch(%r{^spec/.+_spec\.rb$})
3
3
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
4
  watch('spec/spec_helper.rb') { "spec/" }
@@ -23,11 +23,12 @@ class FutureResource
23
23
  ##
24
24
  # Create a new FutureResource.
25
25
  #
26
- def initialize
26
+ def initialize(blocker = nil)
27
27
  @resource_lock = Monitor.new
28
- @resource_value_blocker = @resource_lock.new_cond
28
+ @resource_value_blocker = blocker || @resource_lock.new_cond
29
+ @terminated = false
29
30
  end
30
-
31
+
31
32
  ##
32
33
  # Checks if the value of the resource placeholder has been set yet.
33
34
  #
@@ -38,37 +39,62 @@ class FutureResource
38
39
  end
39
40
 
40
41
  ##
41
- # Returns the value of a specific resource, optionally waiting for `timeout` seconds before raising a Timeout::Error exception.
42
- # When called on a not set resource without a timeout, raises a deadlock.
42
+ # Checks if the attempt to read the resource has been terminated.
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ def terminated?
47
+ !!@resource_lock.synchronize { @terminated }
48
+ end
49
+
50
+ ##
51
+ # Returns the value of a specific resource, optionally waiting for `timeout` seconds before
52
+ # raising a Timeout::Error exception, or raising a FutureResource::Terminated exception if
53
+ # the attempt to read the resource is terminated early by another thread. When called on
54
+ # an unset resource without a timeout, raises a deadlock.
43
55
  #
44
56
  # @param [Integer] timeout number of seconds to wait for the resource to become ready
45
57
  #
46
58
  # @raise [Timeout::Error] if timeout expires and resource is not ready
59
+ # @raise [FutureResource::Terminated] if the attempt to read the resource is terminated by another thread
47
60
  #
48
61
  # @return [Object]
49
62
  #
50
63
  def resource(timeout = nil)
51
64
  Timeout::timeout timeout do
52
65
  @resource_lock.synchronize do
53
- @resource_value_blocker.wait unless defined? @resource
66
+ @resource_value_blocker.wait unless set_yet? or terminated?
67
+ raise Terminated if terminated?
54
68
  @resource
55
69
  end
56
70
  end
57
71
  end
58
-
72
+
59
73
  ##
60
74
  # Sets the value for the resource, making it available for all waiting and following reads.
61
- # Resourcs values can only be set once.
75
+ # Resource values can only be set once. Calling this method on a terminated resource is
76
+ # ineffective.
62
77
  #
63
78
  # @param [Object] resource any value to be set for the resource
64
79
  #
65
80
  # @raise [FutureResource::ResourceAlreadySet] if resource is already set
81
+ #
66
82
  def resource=(resource)
67
- @resource_lock.synchronize do
68
- raise ResourceAlreadySetException if defined? @resource
83
+ set_or_terminate do
69
84
  @resource = resource
70
- @resource_value_blocker.broadcast
71
- @resource_value_blocker = nil # Don't really need it anymore.
85
+ end
86
+ end
87
+
88
+ ##
89
+ # Terminates the attempt to read the resource early, causing those waiting and any
90
+ # following reads to raise a FutureResource::Terminated exception. Subsequently calling
91
+ # this method again is ineffective.
92
+ #
93
+ # @raise [FutureResource::ResourceAlreadySet] if resource is already set
94
+ #
95
+ def terminate
96
+ set_or_terminate do
97
+ @terminated = true
72
98
  end
73
99
  end
74
100
 
@@ -80,4 +106,25 @@ class FutureResource
80
106
  super "Cannot set this resource twice!"
81
107
  end
82
108
  end
109
+
110
+ ##
111
+ # Raised when the attempt to read the resource is terminated early.
112
+ #
113
+ class Terminated < StandardError
114
+ def initialize
115
+ super "Resource read attempt terminated"
116
+ end
117
+ end
118
+
119
+ private
120
+
121
+ def set_or_terminate
122
+ @resource_lock.synchronize do
123
+ return if terminated?
124
+ raise ResourceAlreadySetException if set_yet?
125
+ yield
126
+ @resource_value_blocker.broadcast
127
+ @resource_value_blocker = nil # Don't really need it anymore.
128
+ end
129
+ end
83
130
  end
@@ -1,3 +1,3 @@
1
1
  class FutureResource
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -4,15 +4,21 @@ describe FutureResource do
4
4
  it { should be_instance_of FutureResource }
5
5
 
6
6
  it { should_not be_set_yet }
7
+ it { should_not be_terminated }
7
8
 
8
9
  it "should set resource" do
9
10
  subject.resource = :foo
10
11
  end
11
12
 
13
+ it "should be terminateable" do
14
+ subject.terminate
15
+ end
16
+
12
17
  describe "with a resource set" do
13
18
  before { subject.resource = :foo }
14
19
 
15
20
  it { should be_set_yet }
21
+ it { should_not be_terminated }
16
22
 
17
23
  its(:resource) { should === :foo }
18
24
 
@@ -21,6 +27,37 @@ describe FutureResource do
21
27
  subject.resource = :bar
22
28
  }.to raise_error FutureResource::ResourceAlreadySetException
23
29
  end
30
+
31
+ it "should raise ResourceAlreadySetException when terminating" do
32
+ expect {
33
+ subject.terminate
34
+ }.to raise_error FutureResource::ResourceAlreadySetException
35
+ end
36
+ end
37
+
38
+ describe "that is terminated" do
39
+ before { subject.terminate }
40
+
41
+ it { should_not be_set_yet }
42
+ it { should be_terminated }
43
+
44
+ it "should raise a Terminated exception when getting the resource" do
45
+ expect {
46
+ subject.resource
47
+ }.to raise_error FutureResource::Terminated
48
+ end
49
+
50
+ it "should ignore any attempt to set the resource" do
51
+ subject.resource = :bar
52
+
53
+ expect {
54
+ subject.resource
55
+ }.to raise_error FutureResource::Terminated
56
+ end
57
+
58
+ it "should ignore any attempt to terminate again" do
59
+ subject.terminate
60
+ end
24
61
  end
25
62
 
26
63
  it "should receive the resource value from another thread" do
@@ -30,4 +67,13 @@ describe FutureResource do
30
67
  end
31
68
  subject.resource.should === :foo
32
69
  end
70
+
71
+ it "should allow an alternative condition to be provided" do
72
+ resource = described_class.new(ConditionVariable.new)
73
+ Thread.new do
74
+ sleep 1
75
+ subject.resource = :foo
76
+ end
77
+ subject.resource.should === :foo
78
+ end
33
79
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: future-resource
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
5
- prerelease:
4
+ version: 1.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jay Phillips
@@ -10,74 +9,92 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2012-03-13 00:00:00.000000000 Z
12
+ date: 2013-07-05 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: bundler
17
- requirement: &2164502240 !ruby/object:Gem::Requirement
18
- none: false
16
+ requirement: !ruby/object:Gem::Requirement
19
17
  requirements:
20
- - - ! '>='
18
+ - - '>='
21
19
  - !ruby/object:Gem::Version
22
20
  version: 1.0.0
23
21
  type: :development
24
22
  prerelease: false
25
- version_requirements: *2164502240
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: 1.0.0
26
28
  - !ruby/object:Gem::Dependency
27
29
  name: rspec
28
- requirement: &2164501200 !ruby/object:Gem::Requirement
29
- none: false
30
+ requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
- - - ! '>='
32
+ - - '>='
32
33
  - !ruby/object:Gem::Version
33
34
  version: 2.5.0
34
35
  type: :development
35
36
  prerelease: false
36
- version_requirements: *2164501200
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: 2.5.0
37
42
  - !ruby/object:Gem::Dependency
38
43
  name: ci_reporter
39
- requirement: &2164500260 !ruby/object:Gem::Requirement
40
- none: false
44
+ requirement: !ruby/object:Gem::Requirement
41
45
  requirements:
42
- - - ! '>='
46
+ - - '>='
43
47
  - !ruby/object:Gem::Version
44
48
  version: 1.6.3
45
49
  type: :development
46
50
  prerelease: false
47
- version_requirements: *2164500260
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: 1.6.3
48
56
  - !ruby/object:Gem::Dependency
49
57
  name: yard
50
- requirement: &2164499560 !ruby/object:Gem::Requirement
51
- none: false
58
+ requirement: !ruby/object:Gem::Requirement
52
59
  requirements:
53
- - - ! '>='
60
+ - - '>='
54
61
  - !ruby/object:Gem::Version
55
62
  version: 0.7.0
56
63
  type: :development
57
64
  prerelease: false
58
- version_requirements: *2164499560
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.7.0
59
70
  - !ruby/object:Gem::Dependency
60
71
  name: rake
61
- requirement: &2164499040 !ruby/object:Gem::Requirement
62
- none: false
72
+ requirement: !ruby/object:Gem::Requirement
63
73
  requirements:
64
- - - ! '>='
74
+ - - '>='
65
75
  - !ruby/object:Gem::Version
66
76
  version: '0'
67
77
  type: :development
68
78
  prerelease: false
69
- version_requirements: *2164499040
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
70
84
  - !ruby/object:Gem::Dependency
71
85
  name: guard-rspec
72
- requirement: &2164514760 !ruby/object:Gem::Requirement
73
- none: false
86
+ requirement: !ruby/object:Gem::Requirement
74
87
  requirements:
75
- - - ! '>='
88
+ - - '>='
76
89
  - !ruby/object:Gem::Version
77
90
  version: '0'
78
91
  type: :development
79
92
  prerelease: false
80
- version_requirements: *2164514760
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
81
98
  description: Sometimes a value is set asynchronously and you need to wait until it
82
99
  appears. Easy!
83
100
  email:
@@ -101,27 +118,26 @@ files:
101
118
  - spec/future-resource_spec.rb
102
119
  homepage: https://github.com/adhearsion/future-resource
103
120
  licenses: []
121
+ metadata: {}
104
122
  post_install_message:
105
123
  rdoc_options: []
106
124
  require_paths:
107
125
  - lib
108
126
  required_ruby_version: !ruby/object:Gem::Requirement
109
- none: false
110
127
  requirements:
111
- - - ! '>='
128
+ - - '>='
112
129
  - !ruby/object:Gem::Version
113
130
  version: '0'
114
131
  required_rubygems_version: !ruby/object:Gem::Requirement
115
- none: false
116
132
  requirements:
117
- - - ! '>='
133
+ - - '>='
118
134
  - !ruby/object:Gem::Version
119
135
  version: '0'
120
136
  requirements: []
121
137
  rubyforge_project: future-resource
122
- rubygems_version: 1.8.10
138
+ rubygems_version: 2.0.3
123
139
  signing_key:
124
- specification_version: 3
140
+ specification_version: 4
125
141
  summary: Wait on resources being set in the future
126
142
  test_files:
127
143
  - spec/future-resource_spec.rb