thread 0.0.4.2 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|