thread 0.0.4.2 → 0.0.5
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.
- checksums.yaml +7 -0
- data/README.md +19 -0
- data/lib/thread/pipe.rb +91 -0
- data/thread.gemspec +1 -1
- metadata +8 -10
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1e61241a244fa1f608588c3c156d01f8bad93eff
|
4
|
+
data.tar.gz: 47ad810211ec3eb3f8843d28af75c2f2c593b1ce
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e70de9f4469875502be7c335c380962f7db0bc8737007e008bc37de1f296547dba1c5ca47ab3ef161b68e5c84f3ef85c7a15a1067c770a7cce4d34b068e2d045
|
7
|
+
data.tar.gz: 9b6b631aa5b791a66475898ddbd9ec465f52e254e5caf9d17d41f317dda2df47af64e9b0a72f1b218f941af81c1aa793761dcee832ce6d7199d564fe1e5f5f8f
|
data/README.md
CHANGED
@@ -67,6 +67,25 @@ loop {
|
|
67
67
|
}
|
68
68
|
```
|
69
69
|
|
70
|
+
Pipe
|
71
|
+
====
|
72
|
+
A pipe allows you to execute various tasks on a set of data in parallel,
|
73
|
+
each datum inserted in the pipe is passed along through queues to the various
|
74
|
+
functions composing the pipe, the final result is inserted in the final queue.
|
75
|
+
|
76
|
+
Example
|
77
|
+
-------
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
require 'thread/pipe'
|
81
|
+
|
82
|
+
p = Thread::Pipe.new \
|
83
|
+
|-> d { d * 2 } |-> d { d * 4 }
|
84
|
+
|
85
|
+
p << 2
|
86
|
+
puts ~p
|
87
|
+
```
|
88
|
+
|
70
89
|
Promise
|
71
90
|
=======
|
72
91
|
This implements the promise pattern, allowing you to pass around an object
|
data/lib/thread/pipe.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
require 'thread'
|
12
|
+
|
13
|
+
# A pipe lets you execute various tasks on a set of data in parallel,
|
14
|
+
# each datum inserted in the pipe is passed along through queues to the various
|
15
|
+
# functions composing the pipe, the final result is inserted in the final queue.
|
16
|
+
class Thread::Pipe
|
17
|
+
class Task
|
18
|
+
attr_accessor :input, :output
|
19
|
+
|
20
|
+
def initialize (func, input = Queue.new, output = Queue.new)
|
21
|
+
@input = input
|
22
|
+
@output = output
|
23
|
+
|
24
|
+
@thread = Thread.new {
|
25
|
+
while true
|
26
|
+
begin
|
27
|
+
value = @input.deq
|
28
|
+
value = func.call(value)
|
29
|
+
|
30
|
+
@output.enq value
|
31
|
+
rescue Exception; end
|
32
|
+
end
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def kill
|
37
|
+
@thread.raise
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Create a pipe using the optionally passed objects as input and
|
42
|
+
# output queue.
|
43
|
+
#
|
44
|
+
# The objects must respond to #enq and #deq, and block on #deq.
|
45
|
+
def initialize (input = Queue.new, output = Queue.new)
|
46
|
+
@tasks = []
|
47
|
+
|
48
|
+
@input = input
|
49
|
+
@output = output
|
50
|
+
|
51
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(@tasks))
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.finalize (tasks)
|
55
|
+
proc {
|
56
|
+
tasks.each(&:kill)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
# Insert data in the pipe.
|
61
|
+
def << (data)
|
62
|
+
return if @tasks.empty?
|
63
|
+
|
64
|
+
@input.enq data
|
65
|
+
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
# Add a task to the pipe, it must respond to #call and #arity,
|
70
|
+
# and #arity must return 1.
|
71
|
+
def | (func)
|
72
|
+
if func.arity != 1
|
73
|
+
raise ArgumentError, 'wrong arity'
|
74
|
+
end
|
75
|
+
|
76
|
+
Task.new(func, (@tasks.empty? ? @input : Queue.new), @output).tap {|t|
|
77
|
+
@tasks.last.output = t.input unless @tasks.empty?
|
78
|
+
@tasks << t
|
79
|
+
}
|
80
|
+
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
# Get an element from the output queue.
|
85
|
+
def pop (non_block = false)
|
86
|
+
@output.deq(non_block)
|
87
|
+
end
|
88
|
+
|
89
|
+
alias deq pop
|
90
|
+
alias ~ pop
|
91
|
+
end
|
data/thread.gemspec
CHANGED
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thread
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.5
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- meh.
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
11
|
+
date: 2013-03-28 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
13
|
description: Includes a thread pool, message passing capabilities, a recursive mutex,
|
15
14
|
promise, future and delay.
|
@@ -22,33 +21,32 @@ files:
|
|
22
21
|
- lib/thread/channel.rb
|
23
22
|
- lib/thread/delay.rb
|
24
23
|
- lib/thread/future.rb
|
24
|
+
- lib/thread/pipe.rb
|
25
25
|
- lib/thread/pool.rb
|
26
26
|
- lib/thread/promise.rb
|
27
27
|
- lib/thread/recursive_mutex.rb
|
28
28
|
- thread.gemspec
|
29
29
|
homepage: http://github.com/meh/ruby-thread
|
30
30
|
licenses: []
|
31
|
+
metadata: {}
|
31
32
|
post_install_message:
|
32
33
|
rdoc_options: []
|
33
34
|
require_paths:
|
34
35
|
- lib
|
35
36
|
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
-
none: false
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
42
|
requirements:
|
44
|
-
- -
|
43
|
+
- - '>='
|
45
44
|
- !ruby/object:Gem::Version
|
46
45
|
version: '0'
|
47
46
|
requirements: []
|
48
47
|
rubyforge_project:
|
49
|
-
rubygems_version:
|
48
|
+
rubygems_version: 2.0.0
|
50
49
|
signing_key:
|
51
|
-
specification_version:
|
50
|
+
specification_version: 4
|
52
51
|
summary: Various extensions to the base thread library.
|
53
52
|
test_files: []
|
54
|
-
has_rdoc:
|