thread 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2345d704e37f5dd5742e8e8c69f765a70eb061aa
4
- data.tar.gz: cccad52eb3d6cb3da85dd087c43c4681ddf7c4d2
3
+ metadata.gz: 19359ceb19e36b411191f6a1ad561f7d1d4494b1
4
+ data.tar.gz: 26aa332d8178f937334fb00c01b6d52767aa0164
5
5
  SHA512:
6
- metadata.gz: e3007f09957036eb9e3fa180df9beeb69a429fc8d899fe36fb4a5a1d409bf0baaa1a1104b5b59585362b1d8fe95c26ca25f3aec1ee674b2b76205e2353993d30
7
- data.tar.gz: 1ca741fd5f9a71f2a3c5a023c6e443b346e89d8186f4f854b03cf350eab352f2ee4bc0b50a341b1665aa3b0619e7b10768a2dffb1f32807da64ac6c7ec2d68a7
6
+ metadata.gz: 53b93154104816e06c93c0b4477aa1a65ebc9c878b9e8723881ccf3ea5e2f9ab41c8454b6889018fb0132e9ece4c6efcac3731bff77a987629f4e784ce9d9bfc
7
+ data.tar.gz: 8cd976ebd6c34ac6b0d62facda8da94d67e9fda638f4a62a1d0693c12742ac1a2afca100d4c330de3638a4ea79155c3b08afb01ab1e2ef659365da16f74e9ff9
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ Gemfile.lock
3
+ pkg
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.travis.yml CHANGED
@@ -1,13 +1,10 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - "1.9.2"
5
- - "1.9.3"
6
- - "2.0.0"
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1.0
8
+ - ruby-head
7
9
  - jruby
8
- - rbx
9
-
10
- before_script:
11
- - gem install rspec
12
- - gem build *.gemspec
13
- - gem install *.gem
10
+ - rbx
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.md CHANGED
@@ -1,8 +1,23 @@
1
- thread - various extensions to the thread library
2
- =================================================
1
+ # thread
2
+
3
+ [![Build Status](https://travis-ci.org/meh/ruby-thread.svg?branch=master)](https://travis-ci.org/meh/ruby-thread)
4
+
5
+ Various extensions to the thread library in ruby.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'thread'
12
+
13
+ Or install it yourself as:
14
+
15
+ $ gem install thread
16
+
17
+ ## Usage
18
+
19
+ ### Pool
3
20
 
4
- Pool
5
- ====
6
21
  All the implementations I looked at were either buggy or wasted CPU resources
7
22
  for no apparent reason, for example used a sleep of 0.01 seconds to then check for
8
23
  readiness and stuff like this.
@@ -10,9 +25,6 @@ readiness and stuff like this.
10
25
  This implementation uses standard locking functions to work properly across multiple Ruby
11
26
  implementations.
12
27
 
13
- Example
14
- -------
15
-
16
28
  ```ruby
17
29
  require 'thread/pool'
18
30
 
@@ -31,12 +43,9 @@ pool.shutdown
31
43
 
32
44
  You should get 4 lols every 2 seconds and it should exit after 10 of them.
33
45
 
34
- Channel
35
- =======
36
- This implements a channel where you can write messages and receive messages.
46
+ ### Channel
37
47
 
38
- Example
39
- -------
48
+ This implements a channel where you can write messages and receive messages.
40
49
 
41
50
  ```ruby
42
51
  require 'thread/channel'
@@ -67,15 +76,12 @@ loop {
67
76
  }
68
77
  ```
69
78
 
70
- Pipe
71
- ====
79
+ ### Pipe
80
+
72
81
  A pipe allows you to execute various tasks on a set of data in parallel,
73
82
  each datum inserted in the pipe is passed along through queues to the various
74
83
  functions composing the pipe, the final result is inserted in the final queue.
75
84
 
76
- Example
77
- -------
78
-
79
85
  ```ruby
80
86
  require 'thread/pipe'
81
87
 
@@ -85,16 +91,13 @@ p << 2
85
91
  puts ~p # => 16
86
92
  ```
87
93
 
88
- Process
89
- =======
94
+ ### Process
95
+
90
96
  A process helps reducing programming errors coming from race conditions and the
91
97
  like, the only way to interact with a process is through messages.
92
98
 
93
99
  Multiple processes should talk with eachother through messages.
94
100
 
95
- Example
96
- -------
97
-
98
101
  ```ruby
99
102
  require 'thread/process'
100
103
 
@@ -108,15 +111,12 @@ p << 42
108
111
  p << 23
109
112
  ```
110
113
 
111
- Promise
112
- =======
114
+ ### Promise
115
+
113
116
  This implements the promise pattern, allowing you to pass around an object
114
117
  where you can send a value and extract a value, in a thread-safe way, accessing
115
118
  the value will wait for the value to be delivered.
116
119
 
117
- Example
118
- -------
119
-
120
120
  ```ruby
121
121
  require 'thread/promise'
122
122
 
@@ -130,8 +130,8 @@ Thread.new {
130
130
  puts ~p # => 42
131
131
  ```
132
132
 
133
- Future
134
- ======
133
+ ### Future
134
+
135
135
  A future is somewhat a promise, except you pass it a block to execute in
136
136
  another thread.
137
137
 
@@ -144,9 +144,6 @@ the block executed in an existing thread-pool.
144
144
 
145
145
  You can also use the `Thread::Pool` helper `#future`
146
146
 
147
- Example
148
- -------
149
-
150
147
  ```ruby
151
148
  require 'thread/future'
152
149
 
@@ -186,14 +183,11 @@ puts ~f # => 42
186
183
  ```
187
184
 
188
185
 
189
- Delay
190
- =====
186
+ ### Delay
187
+
191
188
  A delay is kind of a promise, except the block is called when the value is
192
189
  being accessed and the result is cached.
193
190
 
194
- Example
195
- -------
196
-
197
191
  ```ruby
198
192
  require 'thread/delay'
199
193
 
@@ -204,15 +198,12 @@ d = Thread.delay {
204
198
  puts ~d # => 42
205
199
  ```
206
200
 
207
- Every
208
- =====
201
+ ### Every
202
+
209
203
  An every executes the block every given seconds and yields the value to the
210
204
  every object, you can then check if the current value is old or how much time
211
205
  is left until the second call is done.
212
206
 
213
- Example
214
- -------
215
-
216
207
  ```ruby
217
208
  require 'net/http'
218
209
  require 'thread/every'
@@ -227,3 +218,12 @@ loop do
227
218
  puts ~e
228
219
  end
229
220
  ```
221
+
222
+ ## Contributing
223
+
224
+ 1. Fork it ( https://github.com/meh/ruby-thread/fork )
225
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
226
+ 3. Verify new and old specs are green (`rake`)
227
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
228
+ 5. Push to the branch (`git push origin my-new-feature`)
229
+ 6. Create a new Pull Request
data/Rakefile CHANGED
@@ -1,15 +1,6 @@
1
- #! /usr/bin/env ruby
2
- require 'rake'
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
3
 
4
- task :default => :test
4
+ RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :test do
7
- FileUtils.cd 'tests' do
8
- sh 'rspec channel_spec.rb --backtrace --color --format doc'
9
- sh 'rspec promise_spec.rb --backtrace --color --format doc'
10
- sh 'rspec future_spec.rb --backtrace --color --format doc'
11
- sh 'rspec delay_spec.rb --backtrace --color --format doc'
12
- sh 'rspec pipe_spec.rb --backtrace --color --format doc'
13
- sh 'rspec every_spec.rb --backtrace --color --format doc'
14
- end
15
- end
6
+ task :default => :spec
@@ -91,7 +91,7 @@ class Thread::Channel
91
91
  end
92
92
  end
93
93
 
94
- private
94
+ private
95
95
  def cond?
96
96
  instance_variable_defined? :@cond
97
97
  end
data/lib/thread/every.rb CHANGED
@@ -31,7 +31,7 @@ class Thread::Every
31
31
 
32
32
  @mutex.synchronize {
33
33
  @at = Time.now
34
- @value = value
34
+ @value = value
35
35
  @old = false
36
36
  @exception = nil
37
37
  }
@@ -172,7 +172,7 @@ class Thread::Every
172
172
  }
173
173
  end
174
174
 
175
- private
175
+ private
176
176
  def cond?
177
177
  instance_variable_defined? :@cond
178
178
  end
data/lib/thread/future.rb CHANGED
@@ -121,7 +121,7 @@ class Thread::Future
121
121
 
122
122
  alias ! value!
123
123
 
124
- private
124
+ private
125
125
  def cond?
126
126
  instance_variable_defined? :@cond
127
127
  end
data/lib/thread/pipe.rb CHANGED
@@ -106,7 +106,7 @@ class Thread::Pipe
106
106
  def deq (non_block = false)
107
107
  @output.deq(non_block)
108
108
  end
109
-
109
+
110
110
  alias pop deq
111
111
  alias ~ deq
112
112
  end
data/lib/thread/pool.rb CHANGED
@@ -61,6 +61,7 @@ class Thread::Pool
61
61
  return
62
62
  else
63
63
  @exception = reason
64
+ raise @exception if Thread::Pool.abort_on_exception
64
65
  end
65
66
  end
66
67
 
@@ -119,7 +120,7 @@ class Thread::Pool
119
120
 
120
121
  @done = ConditionVariable.new
121
122
  @done_mutex = Mutex.new
122
-
123
+
123
124
  @todo = []
124
125
  @workers = []
125
126
  @timeouts = {}
@@ -200,29 +201,29 @@ class Thread::Pool
200
201
  @done.wait @done_mutex
201
202
  }
202
203
  end
203
-
204
- # Check if there are idle workers.
205
- def idle?
206
- @todo.length < @waiting
207
- end
208
-
209
- # Process Block when there is a idle worker if not block its returns
210
- def idle (&block)
211
- while !idle?
212
- @done_mutex.synchronize {
213
- break if idle?
214
- @done.wait @done_mutex
215
- }
216
- end
217
-
218
- unless block
219
- return
220
- end
221
-
222
- process &block
223
-
224
- end
225
-
204
+
205
+ # Check if there are idle workers.
206
+ def idle?
207
+ @todo.length < @waiting
208
+ end
209
+
210
+ # Process Block when there is a idle worker if not block its returns
211
+ def idle (*args, &block)
212
+ while !idle?
213
+ @done_mutex.synchronize {
214
+ break if idle?
215
+ @done.wait @done_mutex
216
+ }
217
+ end
218
+
219
+ unless block
220
+ return
221
+ end
222
+
223
+ process *args, &block
224
+
225
+ end
226
+
226
227
  # Add a task to the pool which will execute the block with the given
227
228
  # argument.
228
229
  #
@@ -337,7 +338,14 @@ class Thread::Pool
337
338
  self
338
339
  end
339
340
 
340
- private
341
+ class << self
342
+ # If true, tasks will allow raised exceptions to pass through.
343
+ #
344
+ # Similar to Thread.abort_on_exception
345
+ attr_accessor :abort_on_exception
346
+ end
347
+
348
+ private
341
349
  def wake_up_timeout
342
350
  if defined? @pipes
343
351
  @pipes.last.write_nonblock 'x' rescue nil
@@ -398,7 +406,7 @@ private
398
406
 
399
407
  thread
400
408
  end
401
-
409
+
402
410
  def spawn_timeout_thread
403
411
  @pipes = IO.pipe
404
412
  @timeout = Thread.new {
@@ -428,7 +436,7 @@ private
428
436
  }
429
437
 
430
438
  @timeouts.reject! { |task, _| task.terminated? || task.finished? }
431
-
439
+
432
440
  break if @shutdown == :now
433
441
  end
434
442
  }
@@ -446,4 +454,4 @@ class Thread
446
454
  def self.pool (*args, &block)
447
455
  Thread::Pool.new(*args, &block)
448
456
  end
449
- end
457
+ end
@@ -53,7 +53,7 @@ class Thread::Process
53
53
 
54
54
  alias << send
55
55
 
56
- private
56
+ private
57
57
  def receive
58
58
  @channel.receive
59
59
  end
@@ -58,7 +58,7 @@ class Thread::Promise
58
58
 
59
59
  alias ~ value
60
60
 
61
- private
61
+ private
62
62
  def cond?
63
63
  instance_variable_defined? :@cond
64
64
  end
@@ -1,5 +1,3 @@
1
- #! /usr/bin/env ruby
2
- require 'rubygems'
3
1
  require 'thread/channel'
4
2
 
5
3
  describe Thread::Channel do
@@ -1,5 +1,3 @@
1
- #! /usr/bin/env ruby
2
- require 'rubygems'
3
1
  require 'thread/delay'
4
2
 
5
3
  describe Thread::Delay do
@@ -1,10 +1,8 @@
1
- #! /usr/bin/env ruby
2
- require 'rubygems'
3
1
  require 'thread/every'
4
2
 
5
3
  describe Thread::Every do
6
4
  it 'delivers a value properly' do
7
- e = Thread.every(5) { sleep 0.5; 42 }
5
+ e = Thread.every(5) { sleep 0.02; 42 }
8
6
 
9
7
  e.value.should == 42
10
8
  end
@@ -1,12 +1,9 @@
1
- #! /usr/bin/env ruby
2
- require 'rubygems'
3
1
  require 'thread/future'
4
2
 
5
3
  describe Thread::Future do
6
4
  it 'delivers a value properly' do
7
5
  f = Thread.future {
8
- sleep 0.2
9
-
6
+ sleep 0.02
10
7
  42
11
8
  }
12
9
 
@@ -15,19 +12,19 @@ describe Thread::Future do
15
12
 
16
13
  it 'properly checks if anything has been delivered' do
17
14
  f = Thread.future {
18
- sleep 0.2
15
+ sleep 0.02
19
16
 
20
17
  42
21
18
  }
22
19
 
23
20
  f.delivered?.should == false
24
- sleep 0.3
21
+ sleep 0.03
25
22
  f.delivered?.should == true
26
23
  end
27
24
 
28
25
  it 'does not block when a timeout is passed' do
29
26
  f = Thread.future {
30
- sleep 0.2
27
+ sleep 0.02
31
28
 
32
29
  42
33
30
  }
@@ -1,5 +1,3 @@
1
- #! /usr/bin/env ruby
2
- require 'rubygems'
3
1
  require 'thread/pipe'
4
2
 
5
3
  describe Thread::Pipe do
@@ -14,7 +12,7 @@ describe Thread::Pipe do
14
12
  end
15
13
 
16
14
  it 'empty works properly' do
17
- p = Thread |-> d { sleep 0.2; d * 2 } |-> d { d * 4 }
15
+ p = Thread |-> d { sleep 0.02; d * 2 } |-> d { d * 4 }
18
16
 
19
17
  p.empty?.should == true
20
18
  p.enq 42
@@ -1,5 +1,3 @@
1
- #! /usr/bin/env ruby
2
- require 'rubygems'
3
1
  require 'thread/promise'
4
2
 
5
3
  describe Thread::Promise do
@@ -7,7 +5,7 @@ describe Thread::Promise do
7
5
  p = Thread.promise
8
6
 
9
7
  Thread.new {
10
- sleep 0.2
8
+ sleep 0.02
11
9
 
12
10
  p << 42
13
11
  }
@@ -19,13 +17,13 @@ describe Thread::Promise do
19
17
  p = Thread.promise
20
18
 
21
19
  Thread.new {
22
- sleep 0.2
20
+ sleep 0.02
23
21
 
24
22
  p << 42
25
23
  }
26
24
 
27
25
  p.delivered?.should == false
28
- sleep 0.3
26
+ sleep 0.03
29
27
  p.delivered?.should == true
30
28
  end
31
29
 
data/thread.gemspec CHANGED
@@ -1,19 +1,22 @@
1
- Gem::Specification.new {|s|
2
- s.name = 'thread'
3
- s.version = '0.1.4'
4
- s.author = 'meh.'
5
- s.email = 'meh@schizofreni.co'
6
- s.homepage = 'http://github.com/meh/ruby-thread'
7
- s.platform = Gem::Platform::RUBY
8
- s.summary = 'Various extensions to the base thread library.'
9
- s.description = 'Includes a thread pool, message passing capabilities, a recursive mutex, promise, future and delay.'
10
- s.license = 'WTFPL'
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
11
4
 
12
- s.files = `git ls-files`.split("\n")
13
- s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
14
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
- s.require_paths = ['lib']
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "thread"
7
+ spec.version = "0.1.5"
8
+ spec.authors = ["meh."]
9
+ spec.email = ["meh@schizofreni.co"]
10
+ spec.summary = %q{Various extensions to the base thread library.}
11
+ spec.description = %q{Includes a thread pool, message passing capabilities, a recursive mutex, promise, future and delay.}
12
+ spec.homepage = "http://github.com/meh/ruby-thread"
13
+ spec.license = "WTFPL"
16
14
 
17
- s.add_development_dependency 'rspec'
18
- s.add_development_dependency 'rake'
19
- }
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "rspec"
21
+ spec.add_development_dependency "rake"
22
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thread
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - meh.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-18 00:00:00.000000000 Z
11
+ date: 2015-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -40,12 +40,17 @@ dependencies:
40
40
  version: '0'
41
41
  description: Includes a thread pool, message passing capabilities, a recursive mutex,
42
42
  promise, future and delay.
43
- email: meh@schizofreni.co
43
+ email:
44
+ - meh@schizofreni.co
44
45
  executables: []
45
46
  extensions: []
46
47
  extra_rdoc_files: []
47
48
  files:
49
+ - ".gitignore"
50
+ - ".rspec"
48
51
  - ".travis.yml"
52
+ - Gemfile
53
+ - LICENSE.txt
49
54
  - README.md
50
55
  - Rakefile
51
56
  - lib/thread/channel.rb
@@ -57,12 +62,12 @@ files:
57
62
  - lib/thread/process.rb
58
63
  - lib/thread/promise.rb
59
64
  - lib/thread/recursive_mutex.rb
60
- - tests/channel_spec.rb
61
- - tests/delay_spec.rb
62
- - tests/every_spec.rb
63
- - tests/future_spec.rb
64
- - tests/pipe_spec.rb
65
- - tests/promise_spec.rb
65
+ - spec/thread/channel_spec.rb
66
+ - spec/thread/delay_spec.rb
67
+ - spec/thread/every_spec.rb
68
+ - spec/thread/future_spec.rb
69
+ - spec/thread/pipe_spec.rb
70
+ - spec/thread/promise_spec.rb
66
71
  - thread.gemspec
67
72
  homepage: http://github.com/meh/ruby-thread
68
73
  licenses:
@@ -84,9 +89,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
89
  version: '0'
85
90
  requirements: []
86
91
  rubyforge_project:
87
- rubygems_version: 2.2.2
92
+ rubygems_version: 2.4.5
88
93
  signing_key:
89
94
  specification_version: 4
90
95
  summary: Various extensions to the base thread library.
91
- test_files: []
96
+ test_files:
97
+ - spec/thread/channel_spec.rb
98
+ - spec/thread/delay_spec.rb
99
+ - spec/thread/every_spec.rb
100
+ - spec/thread/future_spec.rb
101
+ - spec/thread/pipe_spec.rb
102
+ - spec/thread/promise_spec.rb
92
103
  has_rdoc: