pipeliner 1.0 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/README.rdoc +26 -1
- data/Rakefile +54 -0
- data/lib/pipeliner/Pipeline.rb +31 -12
- data/nbproject/private/private.xml +7 -0
- data/nbproject/private/rake-d.txt +19 -0
- data/nbproject/project.properties +6 -0
- data/nbproject/project.xml +16 -0
- data/pipeliner.gemspec +3 -3
- data/spec/dummy.rb +0 -0
- data/{tests → test}/cases/Filter.rb +0 -0
- data/{tests → test}/cases/FilterManager.rb +0 -0
- data/{tests → test}/cases/Pipeline.rb +16 -1
- data/{tests → test}/run_tests.rb +0 -0
- metadata +42 -20
data/CHANGELOG
CHANGED
data/README.rdoc
CHANGED
@@ -34,7 +34,7 @@ In the example above, we use a simple block to process any String type objects.
|
|
34
34
|
|
35
35
|
require 'pipeliner'
|
36
36
|
|
37
|
-
class Tester
|
37
|
+
class Tester
|
38
38
|
attr_reader :store
|
39
39
|
def initialize
|
40
40
|
@store = []
|
@@ -54,6 +54,31 @@ In the example above, we use a simple block to process any String type objects.
|
|
54
54
|
|
55
55
|
=> ["String", 100, {:test=>:data}]
|
56
56
|
|
57
|
+
Another handy thing is limiting what hooks are called when a very generic type is hooked. When supplying an object method to call, we can also pass a block that provides the condition for which the hook will be run:
|
58
|
+
|
59
|
+
require 'pipeliner'
|
60
|
+
|
61
|
+
class Tester
|
62
|
+
attr_reader :store
|
63
|
+
def initialize
|
64
|
+
@store = []
|
65
|
+
end
|
66
|
+
def process(m)
|
67
|
+
@store << m
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
pipeline = Pipeliner::Pipeline.new
|
72
|
+
obj = Tester.new
|
73
|
+
pipeline.hook(Object, obj, :process){|o| o.is_a?(String) }
|
74
|
+
pipeline << "String"
|
75
|
+
pipeline << 100
|
76
|
+
pipeline << {:test => :data}
|
77
|
+
p obj.store
|
78
|
+
|
79
|
+
=> ["String"]
|
80
|
+
|
81
|
+
|
57
82
|
But, what if you want anything added to the pipeline to be modified before it is distributed out to hooked processors? Well, then you would use a filter:
|
58
83
|
|
59
84
|
require 'pipeliner'
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# To change this template, choose Tools | Templates
|
3
|
+
# and open the template in the editor.
|
4
|
+
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'rake'
|
8
|
+
require 'rake/clean'
|
9
|
+
require 'rake/gempackagetask'
|
10
|
+
require 'rake/rdoctask'
|
11
|
+
require 'rake/testtask'
|
12
|
+
require 'spec/rake/spectask'
|
13
|
+
|
14
|
+
spec = Gem::Specification.new do |s|
|
15
|
+
s.name = 'pipeliner'
|
16
|
+
s.author = 'spox'
|
17
|
+
s.email = 'spox@modspox.com'
|
18
|
+
s.version = '1.1'
|
19
|
+
s.summary = 'Object Pipeline'
|
20
|
+
s.platform = Gem::Platform::RUBY
|
21
|
+
s.files = Dir['**/*']
|
22
|
+
s.rdoc_options = %w(--title pipeliner --main README.rdoc --line-numbers)
|
23
|
+
s.extra_rdoc_files = %w(README.rdoc CHANGELOG)
|
24
|
+
s.require_paths = %w(lib)
|
25
|
+
s.required_ruby_version = '>= 1.8.6'
|
26
|
+
s.add_dependency 'actionpool', '~> 0.2.3'
|
27
|
+
s.add_dependency 'splib', '~> 1.4.3'
|
28
|
+
s.homepage = %q(http://github.com/spox/pipeliner)
|
29
|
+
s.description = "Simple library to allow pipeline styled communications between objects"
|
30
|
+
end
|
31
|
+
|
32
|
+
Rake::GemPackageTask.new(spec) do |p|
|
33
|
+
p.gem_spec = spec
|
34
|
+
p.need_tar = true
|
35
|
+
p.need_zip = true
|
36
|
+
end
|
37
|
+
|
38
|
+
Rake::RDocTask.new do |rdoc|
|
39
|
+
files =['README', 'LICENSE', 'lib/**/*.rb']
|
40
|
+
rdoc.rdoc_files.add(files)
|
41
|
+
rdoc.main = "README" # page to start on
|
42
|
+
rdoc.title = "pipeliner Docs"
|
43
|
+
rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
|
44
|
+
rdoc.options << '--line-numbers'
|
45
|
+
end
|
46
|
+
|
47
|
+
Rake::TestTask.new do |t|
|
48
|
+
t.test_files = FileList['test/**/*.rb']
|
49
|
+
end
|
50
|
+
|
51
|
+
Spec::Rake::SpecTask.new do |t|
|
52
|
+
t.spec_files = FileList['spec/**/*.rb']
|
53
|
+
t.libs << Dir["lib"]
|
54
|
+
end
|
data/lib/pipeliner/Pipeline.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'actionpool'
|
2
|
+
require 'splib'
|
3
|
+
require 'pipeliner/FilterManager'
|
2
4
|
|
3
5
|
Splib.load :Constants
|
4
6
|
|
@@ -13,17 +15,21 @@ module Pipeliner
|
|
13
15
|
@hooks = {}
|
14
16
|
@lock = Mutex.new
|
15
17
|
@filters = args[:filters] ? args[:filters] : FilterManager.new
|
18
|
+
if(!args[:pool])
|
19
|
+
Kernel.at_exit do
|
20
|
+
close
|
21
|
+
end
|
22
|
+
end
|
16
23
|
end
|
17
24
|
|
18
25
|
# Close the pipeline
|
19
|
-
# Note: This is important to at the end of a script when not
|
26
|
+
# Note: This is important to call at the end of a script when not
|
20
27
|
# providing an ActionPool thread pool to the pipeline.
|
21
28
|
# This will ensure the thread pool is properly shutdown
|
22
29
|
# and avoid the script hanging.
|
23
30
|
def close
|
24
31
|
@pool.shutdown
|
25
32
|
clear
|
26
|
-
@pool = nil
|
27
33
|
end
|
28
34
|
|
29
35
|
# Open the pipeline
|
@@ -46,25 +52,38 @@ module Pipeliner
|
|
46
52
|
# type:: Type of Objects to pass to object
|
47
53
|
# object:: Object to hook to pipeline
|
48
54
|
# method:: Method to call on object
|
49
|
-
# block:: Block to apply to object (called without object and method set)
|
50
|
-
# Hooks an Object into the pipeline for objects of a given type
|
55
|
+
# block:: Block to apply to object (called without object and method set) or conditional
|
56
|
+
# Hooks an Object into the pipeline for objects of a given type. The block can serve
|
57
|
+
# two purposes here. First, we can hook a block to a type like so:
|
58
|
+
# pipeline.hook(String){|s| puts s }
|
59
|
+
# Or, we can use the block as a conditional for calling an object's method:
|
60
|
+
# pipeline.hook(String, obj, :method){|s| s == 'test' }
|
61
|
+
# In the second example, this hook will only be called if the String type object
|
62
|
+
# matches the conditional in the block, meaning the string must be 'test'
|
51
63
|
def hook(type, object=nil, method=nil, &block)
|
52
|
-
raise ArgumentError.new
|
53
|
-
|
64
|
+
raise ArgumentError.new 'Type must be provided' if type.nil?
|
65
|
+
if(block && (block.arity > 1 || block.arity == 0))
|
66
|
+
raise ArgumentError.new('Block must accept a parameter')
|
67
|
+
end
|
68
|
+
if((object && method.nil?) || (object.nil? && method))
|
69
|
+
raise ArgumentError.new('Object AND method must be provided')
|
70
|
+
end
|
71
|
+
if(!block_given? && object.nil? && method.nil?)
|
72
|
+
raise ArgumentError.new('No object information or block provided for hook')
|
73
|
+
end
|
54
74
|
@lock.synchronize do
|
55
75
|
const = Splib.find_const(type)
|
56
76
|
type = const unless const.nil?
|
57
77
|
@hooks[type] ||= {}
|
58
|
-
if(block_given?)
|
78
|
+
if(block_given? && object.nil? && method.nil?)
|
59
79
|
@hooks[type][:procs] ||= []
|
60
80
|
@hooks[type][:procs] << block
|
61
|
-
|
62
|
-
if(object && method)
|
81
|
+
else
|
63
82
|
name = object.class
|
64
83
|
method = method.to_sym
|
65
84
|
raise ArgumentError.new('Given object does not respond to given method') unless object.respond_to?(method)
|
66
85
|
@hooks[type][name] ||= []
|
67
|
-
@hooks[type][name] << {:object => object, :method => method}
|
86
|
+
@hooks[type][name] << {:object => object, :method => method, :req => !block_given? ? lambda{|x|true} : block}
|
68
87
|
end
|
69
88
|
end
|
70
89
|
block_given? ? block : nil
|
@@ -144,7 +163,7 @@ module Pipeliner
|
|
144
163
|
if(key == :procs)
|
145
164
|
objects.each{|pr| @pool.process{ pr.call(o) }}
|
146
165
|
else
|
147
|
-
objects.each{|h| @pool.process{ h[:object].send(h[:method], o)}}
|
166
|
+
objects.each{|h| @pool.process{ h[:object].send(h[:method], o) if h[:req].call(o) }}
|
148
167
|
end
|
149
168
|
end
|
150
169
|
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
3
|
+
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
|
4
|
+
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/1">
|
5
|
+
<file>file:/home/spox/NetBeansProjects/pipeliner/lib/pipeliner/Pipeline.rb</file>
|
6
|
+
</open-files>
|
7
|
+
</project-private>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
clean=Remove any temporary products.
|
2
|
+
clobber=Remove any generated file.
|
3
|
+
clobber_package=Remove package products
|
4
|
+
clobber_rdoc=Remove rdoc products
|
5
|
+
doc=
|
6
|
+
doc/rdoc=
|
7
|
+
doc/rdoc/index.html=
|
8
|
+
gem=Build the gem file pipeliner-1.1.gem
|
9
|
+
package=Build all the packages
|
10
|
+
pkg=
|
11
|
+
pkg/pipeliner-1.1=
|
12
|
+
pkg/pipeliner-1.1.gem=
|
13
|
+
pkg/pipeliner-1.1.tgz=
|
14
|
+
pkg/pipeliner-1.1.zip=
|
15
|
+
rdoc=Build the rdoc HTML Files
|
16
|
+
repackage=Force a rebuild of the package files
|
17
|
+
rerdoc=Force a rebuild of the RDOC files
|
18
|
+
spec=Run specs
|
19
|
+
test=Run tests
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<project xmlns="http://www.netbeans.org/ns/project/1">
|
3
|
+
<type>org.netbeans.modules.ruby.rubyproject</type>
|
4
|
+
<configuration>
|
5
|
+
<data xmlns="http://www.netbeans.org/ns/ruby-project/1">
|
6
|
+
<name>pipeliner</name>
|
7
|
+
<source-roots>
|
8
|
+
<root id="src.dir"/>
|
9
|
+
</source-roots>
|
10
|
+
<test-roots>
|
11
|
+
<root id="test.src.dir"/>
|
12
|
+
<root id="spec.src.dir"/>
|
13
|
+
</test-roots>
|
14
|
+
</data>
|
15
|
+
</configuration>
|
16
|
+
</project>
|
data/pipeliner.gemspec
CHANGED
@@ -2,7 +2,7 @@ spec = Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'pipeliner'
|
3
3
|
s.author = 'spox'
|
4
4
|
s.email = 'spox@modspox.com'
|
5
|
-
s.version = '1.
|
5
|
+
s.version = '1.1'
|
6
6
|
s.summary = 'Object Pipeline'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.files = Dir['**/*']
|
@@ -10,8 +10,8 @@ spec = Gem::Specification.new do |s|
|
|
10
10
|
s.extra_rdoc_files = %w(README.rdoc CHANGELOG)
|
11
11
|
s.require_paths = %w(lib)
|
12
12
|
s.required_ruby_version = '>= 1.8.6'
|
13
|
-
s.add_dependency '
|
14
|
-
s.add_dependency 'splib', '~> 1.
|
13
|
+
s.add_dependency 'actionpool', '~> 0.2.3'
|
14
|
+
s.add_dependency 'splib', '~> 1.4.3'
|
15
15
|
s.homepage = %q(http://github.com/spox/pipeliner)
|
16
16
|
s.description = "Simple library to allow pipeline styled communications between objects"
|
17
17
|
end
|
data/spec/dummy.rb
ADDED
File without changes
|
File without changes
|
File without changes
|
@@ -32,7 +32,7 @@ class PipelineTest < Test::Unit::TestCase
|
|
32
32
|
end
|
33
33
|
def test_hook_addition
|
34
34
|
assert_raise(ArgumentError){ @pipeline.hook(String) }
|
35
|
-
assert_raise(ArgumentError){ @pipeline.hook(String){ true } }
|
35
|
+
assert_raise(ArgumentError){ @pipeline.hook(String){ true } } if RUBY_VERSION >= '1.9.0'
|
36
36
|
assert_raise(ArgumentError){ @pipeline.hook(String){|a,b| true} }
|
37
37
|
assert_kind_of(Proc, @pipeline.hook(String){|a| true })
|
38
38
|
assert_kind_of(Proc, @pipeline.hook(String){|a, *b| true })
|
@@ -70,6 +70,20 @@ class PipelineTest < Test::Unit::TestCase
|
|
70
70
|
@pipeline.clear
|
71
71
|
assert(@pipeline.hooks.empty?)
|
72
72
|
end
|
73
|
+
def test_hook_conditional
|
74
|
+
obj = Tester.new
|
75
|
+
@pipeline.hook(String, obj, :method)
|
76
|
+
@pipeline << "test"
|
77
|
+
sleep(0.01)
|
78
|
+
assert_equal(1, obj.messages.size)
|
79
|
+
@pipeline.hook(String, obj, :method){|s| s == 'test' }
|
80
|
+
@pipeline << "fubar"
|
81
|
+
sleep(0.01)
|
82
|
+
assert_equal(2, obj.messages.size)
|
83
|
+
@pipeline << "test"
|
84
|
+
sleep(0.01)
|
85
|
+
assert_equal(4, obj.messages.size)
|
86
|
+
end
|
73
87
|
def test_flush
|
74
88
|
out = []
|
75
89
|
assert(out.empty?)
|
@@ -100,6 +114,7 @@ class PipelineTest < Test::Unit::TestCase
|
|
100
114
|
@pipeline.filters.add(String){|s|10}
|
101
115
|
@pipeline.hook(Object){|s|out << s}
|
102
116
|
@pipeline << 'fubar'
|
117
|
+
sleep(0.01)
|
103
118
|
assert(out.include?(10))
|
104
119
|
assert(!out.include?('fubar'))
|
105
120
|
@pipeline.filters.clear
|
data/{tests → test}/run_tests.rb
RENAMED
File without changes
|
metadata
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pipeliner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 1
|
8
|
+
version: "1.1"
|
5
9
|
platform: ruby
|
6
10
|
authors:
|
7
11
|
- spox
|
@@ -9,29 +13,37 @@ autorequire:
|
|
9
13
|
bindir: bin
|
10
14
|
cert_chain: []
|
11
15
|
|
12
|
-
date:
|
16
|
+
date: 2010-04-20 00:00:00 -07:00
|
13
17
|
default_executable:
|
14
18
|
dependencies:
|
15
19
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
17
|
-
|
18
|
-
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
name: actionpool
|
21
|
+
prerelease: false
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
23
|
requirements:
|
21
24
|
- - ~>
|
22
25
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
26
|
+
segments:
|
27
|
+
- 0
|
28
|
+
- 2
|
29
|
+
- 3
|
30
|
+
version: 0.2.3
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
25
33
|
- !ruby/object:Gem::Dependency
|
26
34
|
name: splib
|
27
|
-
|
28
|
-
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
37
|
requirements:
|
31
38
|
- - ~>
|
32
39
|
- !ruby/object:Gem::Version
|
33
|
-
|
34
|
-
|
40
|
+
segments:
|
41
|
+
- 1
|
42
|
+
- 4
|
43
|
+
- 3
|
44
|
+
version: 1.4.3
|
45
|
+
type: :runtime
|
46
|
+
version_requirements: *id002
|
35
47
|
description: Simple library to allow pipeline styled communications between objects
|
36
48
|
email: spox@modspox.com
|
37
49
|
executables: []
|
@@ -42,14 +54,20 @@ extra_rdoc_files:
|
|
42
54
|
- README.rdoc
|
43
55
|
- CHANGELOG
|
44
56
|
files:
|
45
|
-
-
|
46
|
-
-
|
47
|
-
-
|
48
|
-
-
|
57
|
+
- spec/dummy.rb
|
58
|
+
- test/cases/Filter.rb
|
59
|
+
- test/cases/FilterManager.rb
|
60
|
+
- test/cases/Pipeline.rb
|
61
|
+
- test/run_tests.rb
|
62
|
+
- nbproject/private/rake-d.txt
|
63
|
+
- nbproject/private/private.xml
|
64
|
+
- nbproject/project.xml
|
65
|
+
- nbproject/project.properties
|
49
66
|
- lib/pipeliner/Filter.rb
|
50
67
|
- lib/pipeliner/FilterManager.rb
|
51
68
|
- lib/pipeliner/Pipeline.rb
|
52
69
|
- lib/pipeliner.rb
|
70
|
+
- Rakefile
|
53
71
|
- CHANGELOG
|
54
72
|
- LICENSE
|
55
73
|
- README.rdoc
|
@@ -71,18 +89,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
71
89
|
requirements:
|
72
90
|
- - ">="
|
73
91
|
- !ruby/object:Gem::Version
|
92
|
+
segments:
|
93
|
+
- 1
|
94
|
+
- 8
|
95
|
+
- 6
|
74
96
|
version: 1.8.6
|
75
|
-
version:
|
76
97
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
98
|
requirements:
|
78
99
|
- - ">="
|
79
100
|
- !ruby/object:Gem::Version
|
101
|
+
segments:
|
102
|
+
- 0
|
80
103
|
version: "0"
|
81
|
-
version:
|
82
104
|
requirements: []
|
83
105
|
|
84
106
|
rubyforge_project:
|
85
|
-
rubygems_version: 1.3.
|
107
|
+
rubygems_version: 1.3.6
|
86
108
|
signing_key:
|
87
109
|
specification_version: 3
|
88
110
|
summary: Object Pipeline
|