future-resource 1.0.0 → 1.1.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.
@@ -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