pacer-parallel 0.1.0-java
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/.gitignore +18 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +70 -0
- data/Rakefile +19 -0
- data/pacer-parallel.gemspec +26 -0
- data/project.clj +28 -0
- data/src/clojure/pacer/parallel.clj +23 -0
- data/src/java/com/xnlogic/pacer/ChannelCapPipe.java +47 -0
- data/src/java/com/xnlogic/pacer/ChannelFanInPipe.java +41 -0
- data/src/java/com/xnlogic/pacer/ChannelReaderPipe.java +33 -0
- data/src/ruby/pacer-parallel.rb +1 -0
- data/src/ruby/pacer/clojure.rb +13 -0
- data/src/ruby/pacer/parallel.rb +28 -0
- data/src/ruby/pacer/parallel/channel_cap.rb +29 -0
- data/src/ruby/pacer/parallel/channel_fan_in.rb +27 -0
- data/src/ruby/pacer/parallel/channel_reader.rb +24 -0
- data/src/ruby/pacer/parallel/version.rb +9 -0
- data/target/release/pacer.parallel-0.1.0-SNAPSHOT-standalone.jar +0 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 45fecca778590a9eedc6c7386894dd14847fb538
|
4
|
+
data.tar.gz: 07d3840329d2aaa564b395313ce622395058c6ba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f1f15ee12ce896353781f578924cd6912f1bfda5d776c740a8ed79582e8dd9dcedc820b215263fd487bc35fe4cbdd507901a5d74559264c14f88b8594e94333f
|
7
|
+
data.tar.gz: 6dc2fab326c7ccfb7318e6be352b8309c0218f00fb13d0cfe5afc3203b9ba639a18aed6de70a8d93b877e8777d06537a268b456bfdbc0ca635288a61fed417fe
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Darrick Wiebe
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Pacer::Parallel
|
2
|
+
|
3
|
+
Parallelize [Pacer](https://github.com/pangloss/pacer) Routes.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'pacer-parallel'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install pacer-parallel
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
g.v.parallel(threads: 8, in_buffer: 4, out_buffer: 10) do |v|
|
23
|
+
v.all(&:out)
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create new Pull Request
|
34
|
+
|
35
|
+
|
36
|
+
## Notes
|
37
|
+
|
38
|
+
|
39
|
+
* eagerly consume (1) input and push into a channel
|
40
|
+
* ChannelCapPipe
|
41
|
+
* create a cap pipe that does this. The pipe's output is the channel
|
42
|
+
* source data may be slow. Should probably not use a go block
|
43
|
+
* 1 thread in a loop
|
44
|
+
* Control the construction of parallel pipes. Default 2 threads, make
|
45
|
+
it configurable.
|
46
|
+
* standard copy split pipe can push the channel to subchannels
|
47
|
+
* each parallel route pulls from the channel.
|
48
|
+
* in a go block (waits will not block go thread pool)
|
49
|
+
* ChannelReaderPipe
|
50
|
+
* PathChannelReaderPipe
|
51
|
+
* parallel routes are unmodified
|
52
|
+
* cap each route - eagerly consume input and push into a channel
|
53
|
+
* ChannelCapPipe again
|
54
|
+
* ExhaustMergePipe + GatherPipe to create a route to an list of
|
55
|
+
channels
|
56
|
+
* use alts to read from any of the channels
|
57
|
+
* ChannelFanInPipe
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
## Pipe structure built to create parallel route:
|
62
|
+
|
63
|
+
CCP
|
64
|
+
CSP (parallelism is 1 thread per pipe being split into)
|
65
|
+
CRP -> Work ... -> CCP
|
66
|
+
CRP -> Work ... -> CCP
|
67
|
+
...
|
68
|
+
EMP
|
69
|
+
GP
|
70
|
+
CARP
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
task :package do
|
4
|
+
system 'lein', 'with-profile', 'release', 'uberjar'
|
5
|
+
end
|
6
|
+
|
7
|
+
file Pacer::Parallel::JAR_PATH => FileList['project.clj', 'src/clojure/**/*.clj', 'src/java/**/*.java'] do
|
8
|
+
Rake::Task['package'].execute
|
9
|
+
end
|
10
|
+
|
11
|
+
task :jar => Pacer::Parallel::JAR_PATH
|
12
|
+
|
13
|
+
task :build => :jar
|
14
|
+
task :install => :jar
|
15
|
+
|
16
|
+
desc "Run the clojure test and integration suites"
|
17
|
+
task :expectations do
|
18
|
+
sh "lein with-profile integration expectations"
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../src/ruby', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'pacer/parallel/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "pacer-parallel"
|
8
|
+
spec.version = Pacer::Parallel::VERSION
|
9
|
+
spec.platform = 'java'
|
10
|
+
spec.authors = ["Darrick Wiebe"]
|
11
|
+
spec.email = ["dw@xnlogic.com"]
|
12
|
+
spec.description = %q{Simple parallel routes in Pacer}
|
13
|
+
spec.summary = %q{With the magic of Clojure's core.async}
|
14
|
+
spec.homepage = "http://xnlogic.com"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/) + [Pacer::Parallel::JAR_PATH]
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["src/ruby"]
|
21
|
+
|
22
|
+
spec.add_dependency "pacer", "~> 1.3.3"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
end
|
data/project.clj
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
(defproject
|
2
|
+
pacer.parallel "0.1.0-SNAPSHOT"
|
3
|
+
:description "Leveraging core.async in Pacer"
|
4
|
+
:url "http://xnlogic.com"
|
5
|
+
:license {:name "MIT"}
|
6
|
+
:min-lein-version "2.0.0"
|
7
|
+
:dependencies [[org.clojure/clojure "1.5.1"]
|
8
|
+
[core.async "0.1.0-SNAPSHOT"]
|
9
|
+
[com.tinkerpop/pipes "2.3.0"]]
|
10
|
+
:global-vars {*warn-on-reflection* true}
|
11
|
+
:profiles
|
12
|
+
{:dev
|
13
|
+
{:source-paths ["src/clojure"]
|
14
|
+
:java-source-paths ["src/java"]}
|
15
|
+
:release
|
16
|
+
{:source-paths ["src/clojure"]
|
17
|
+
:java-source-paths ["src/java"]
|
18
|
+
:target-path "target/release"}
|
19
|
+
:integration
|
20
|
+
{:source-paths ["src/clojure"]
|
21
|
+
:java-source-paths ["src/java"]
|
22
|
+
:test-paths ["test_integration"]
|
23
|
+
:target-path "target/integration"}
|
24
|
+
}
|
25
|
+
:plugins [[lein-expectations "0.0.7"]
|
26
|
+
[lein-autoexpect "0.2.5"]
|
27
|
+
[lein-kibit "0.0.7"]
|
28
|
+
])
|
@@ -0,0 +1,23 @@
|
|
1
|
+
(ns pacer.parallel
|
2
|
+
(:require [clojure.core.async :refer [chan >!! close! alts!!]])
|
3
|
+
(:import com.tinkerpop.pipes.Pipe))
|
4
|
+
|
5
|
+
(defn pipe->chan [^Pipe pipe buffer]
|
6
|
+
(let [c (if buffer (chan buffer) (chan))]
|
7
|
+
(if (.hasNext pipe)
|
8
|
+
(future
|
9
|
+
(loop [v (.next pipe)]
|
10
|
+
(when v (>!! c v))
|
11
|
+
(if (.hasNext pipe)
|
12
|
+
(recur (.next pipe))
|
13
|
+
(close! c))))
|
14
|
+
(close! c))
|
15
|
+
c))
|
16
|
+
|
17
|
+
(defn chan-select [chans]
|
18
|
+
(let [[v c] (alts!! chans)]
|
19
|
+
(if v
|
20
|
+
[v chans]
|
21
|
+
(if (= 1 (count chans))
|
22
|
+
nil
|
23
|
+
(recur (remove #{c} chans))))))
|
@@ -0,0 +1,47 @@
|
|
1
|
+
package com.xnlogic.pacer;
|
2
|
+
|
3
|
+
import com.tinkerpop.pipes.AbstractPipe;
|
4
|
+
import com.tinkerpop.pipes.Pipe;
|
5
|
+
import com.tinkerpop.pipes.transform.TransformPipe;
|
6
|
+
import com.tinkerpop.pipes.util.FastNoSuchElementException;
|
7
|
+
|
8
|
+
import clojure.lang.RT;
|
9
|
+
import clojure.lang.Var;
|
10
|
+
import clojure.lang.Symbol;
|
11
|
+
|
12
|
+
public class ChannelCapPipe<S> extends AbstractPipe<S, Object> implements TransformPipe<S, Object> {
|
13
|
+
private static final Var REQUIRE = RT.var("clojure.core", "require");
|
14
|
+
private static final Var PIPE_TO_CHAN = RT.var("pacer.parallel", "pipe->chan");
|
15
|
+
private static boolean environmentReady = false;
|
16
|
+
|
17
|
+
public static void setupEnvironment() {
|
18
|
+
if (!ChannelCapPipe.environmentReady) {
|
19
|
+
REQUIRE.invoke(Symbol.intern(null, "clojure.core"));
|
20
|
+
REQUIRE.invoke(Symbol.intern(null, "pacer.parallel"));
|
21
|
+
REQUIRE.invoke(Symbol.intern(null, "clojure.core.async"));
|
22
|
+
ChannelCapPipe.environmentReady = true;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
|
27
|
+
private Object buffer;
|
28
|
+
private boolean hasRun = false;
|
29
|
+
|
30
|
+
public ChannelCapPipe(Object buffer) {
|
31
|
+
ChannelCapPipe.setupEnvironment();
|
32
|
+
this.buffer = buffer;
|
33
|
+
}
|
34
|
+
|
35
|
+
protected Object processNextStart() {
|
36
|
+
if (!this.hasRun) {
|
37
|
+
this.hasRun = true;
|
38
|
+
return PIPE_TO_CHAN.invoke(starts, buffer);
|
39
|
+
} else {
|
40
|
+
throw FastNoSuchElementException.instance();
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
public void reset() {
|
45
|
+
this.hasRun = false;
|
46
|
+
}
|
47
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
package com.xnlogic.pacer;
|
2
|
+
|
3
|
+
import com.tinkerpop.pipes.AbstractPipe;
|
4
|
+
import com.tinkerpop.pipes.Pipe;
|
5
|
+
import com.tinkerpop.pipes.transform.TransformPipe;
|
6
|
+
import com.tinkerpop.pipes.util.FastNoSuchElementException;
|
7
|
+
|
8
|
+
import java.util.List;
|
9
|
+
import clojure.lang.RT;
|
10
|
+
import clojure.lang.Var;
|
11
|
+
|
12
|
+
public class ChannelFanInPipe<S> extends AbstractPipe<List<Object>, S> implements TransformPipe<List<Object>, S> {
|
13
|
+
private static final Var VEC = RT.var("clojure.core", "vec");
|
14
|
+
private static final Var NTH = RT.var("clojure.core", "nth");
|
15
|
+
private static final Var CHAN_SELECT = RT.var("pacer.parallel", "chan-select");
|
16
|
+
|
17
|
+
private Object chans;
|
18
|
+
|
19
|
+
protected S processNextStart() {
|
20
|
+
while (true) {
|
21
|
+
if (this.chans == null) {
|
22
|
+
Object next = starts.next();
|
23
|
+
if (next != null)
|
24
|
+
this.chans = VEC.invoke(next);
|
25
|
+
} else {
|
26
|
+
Object vec = CHAN_SELECT.invoke(this.chans);
|
27
|
+
if (vec == null) {
|
28
|
+
this.chans = null;
|
29
|
+
} else {
|
30
|
+
this.chans = NTH.invoke(vec, 1);
|
31
|
+
return (S) NTH.invoke(vec, 0);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
public void reset() {
|
38
|
+
this.chans = null;
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
package com.xnlogic.pacer;
|
2
|
+
|
3
|
+
import com.tinkerpop.pipes.AbstractPipe;
|
4
|
+
import com.tinkerpop.pipes.Pipe;
|
5
|
+
import com.tinkerpop.pipes.transform.TransformPipe;
|
6
|
+
import com.tinkerpop.pipes.util.FastNoSuchElementException;
|
7
|
+
|
8
|
+
import clojure.lang.RT;
|
9
|
+
import clojure.lang.Var;
|
10
|
+
|
11
|
+
public class ChannelReaderPipe<S> extends AbstractPipe<S, Object> implements TransformPipe<S, Object> {
|
12
|
+
private static final Var READ_CHAN = RT.var("clojure.core.async", "<!!");
|
13
|
+
|
14
|
+
private Object chan;
|
15
|
+
|
16
|
+
protected Object processNextStart() {
|
17
|
+
while (true) {
|
18
|
+
if (this.chan == null) {
|
19
|
+
this.chan = starts.next();
|
20
|
+
} else {
|
21
|
+
Object value = READ_CHAN.invoke(this.chan);
|
22
|
+
if (value == null)
|
23
|
+
this.chan = null;
|
24
|
+
else
|
25
|
+
return value;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
public void reset() {
|
31
|
+
this.chan = null;
|
32
|
+
}
|
33
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'pacer/parallel'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "pacer/parallel/version"
|
2
|
+
require File.join(Pacer::Parallel::PATH, Pacer::Parallel::JAR_PATH)
|
3
|
+
require "pacer/clojure"
|
4
|
+
require 'pacer'
|
5
|
+
require "pacer/parallel/channel_cap"
|
6
|
+
require "pacer/parallel/channel_reader"
|
7
|
+
require "pacer/parallel/channel_fan_in"
|
8
|
+
|
9
|
+
module Pacer
|
10
|
+
module Routes
|
11
|
+
module RouteOperations
|
12
|
+
def parallel(opts = {}, &block)
|
13
|
+
threads = opts.fetch(:threads, 2)
|
14
|
+
if threads > 0
|
15
|
+
branched = (0...threads).reduce(channel_cap buffer: opts.fetch(:in_buffer, threads)) do |r, n|
|
16
|
+
r.branch do |x|
|
17
|
+
b = block.call x.channel_reader(based_on: self)
|
18
|
+
b.channel_cap buffer: opts[:out_buffer]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
branched.merge_exhaustive.gather.channel_fan_in(based_on: block.call(self))
|
22
|
+
else
|
23
|
+
block.call self
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Pacer
|
2
|
+
module Routes
|
3
|
+
module RouteOperations
|
4
|
+
# This creates a channel, emits it and spawns a thread
|
5
|
+
# that will push all data in the source into the channel.
|
6
|
+
def channel_cap(opts = {})
|
7
|
+
chain_route(opts.merge transform: Pacer::Parallel::ChannelCap, element_type: :channel)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Parallel
|
13
|
+
module ChannelCap
|
14
|
+
import com.xnlogic.pacer.ChannelCapPipe
|
15
|
+
|
16
|
+
attr_accessor :buffer
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def attach_pipe(end_pipe)
|
21
|
+
pipe = ChannelCapPipe.new(buffer)
|
22
|
+
pipe.setStarts end_pipe if end_pipe
|
23
|
+
pipe
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Pacer
|
2
|
+
module Routes
|
3
|
+
module RouteOperations
|
4
|
+
# The source of this should be a pipe emitting lists of channels.
|
5
|
+
def channel_fan_in(opts = {})
|
6
|
+
chain_route(opts.merge transform: Pacer::Parallel::ChannelFanIn)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Parallel
|
12
|
+
module ChannelFanIn
|
13
|
+
import com.xnlogic.pacer.ChannelFanInPipe
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def attach_pipe(end_pipe)
|
18
|
+
pipe = ChannelFanInPipe.new
|
19
|
+
pipe.setStarts end_pipe if end_pipe
|
20
|
+
pipe
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Pacer
|
2
|
+
module Routes
|
3
|
+
module RouteOperations
|
4
|
+
# The source of this in a pipe emitting individual channels
|
5
|
+
def channel_reader(opts = {})
|
6
|
+
chain_route(opts.merge transform: Pacer::Parallel::ChannelReader)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Parallel
|
12
|
+
module ChannelReader
|
13
|
+
import com.xnlogic.pacer.ChannelReaderPipe
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def attach_pipe(end_pipe)
|
18
|
+
pipe = ChannelReaderPipe.new
|
19
|
+
pipe.setStarts end_pipe if end_pipe
|
20
|
+
pipe
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Pacer
|
2
|
+
module Parallel
|
3
|
+
VERSION = "0.1.0"
|
4
|
+
JAR_VERSION = "#{VERSION}-SNAPSHOT"
|
5
|
+
JAR = "pacer.parallel-#{ JAR_VERSION }-standalone.jar"
|
6
|
+
JAR_PATH = "target/release/#{ JAR }"
|
7
|
+
PATH = File.expand_path(File.join(File.dirname(__FILE__), '../../../..'))
|
8
|
+
end
|
9
|
+
end
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pacer-parallel
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: java
|
6
|
+
authors:
|
7
|
+
- Darrick Wiebe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pacer
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.3.3
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.3.3
|
25
|
+
prerelease: false
|
26
|
+
type: :runtime
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '1.3'
|
39
|
+
prerelease: false
|
40
|
+
type: :development
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
prerelease: false
|
54
|
+
type: :development
|
55
|
+
description: Simple parallel routes in Pacer
|
56
|
+
email:
|
57
|
+
- dw@xnlogic.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- pacer-parallel.gemspec
|
68
|
+
- project.clj
|
69
|
+
- src/clojure/pacer/parallel.clj
|
70
|
+
- src/java/com/xnlogic/pacer/ChannelCapPipe.java
|
71
|
+
- src/java/com/xnlogic/pacer/ChannelFanInPipe.java
|
72
|
+
- src/java/com/xnlogic/pacer/ChannelReaderPipe.java
|
73
|
+
- src/ruby/pacer-parallel.rb
|
74
|
+
- src/ruby/pacer/clojure.rb
|
75
|
+
- src/ruby/pacer/parallel.rb
|
76
|
+
- src/ruby/pacer/parallel/channel_cap.rb
|
77
|
+
- src/ruby/pacer/parallel/channel_fan_in.rb
|
78
|
+
- src/ruby/pacer/parallel/channel_reader.rb
|
79
|
+
- src/ruby/pacer/parallel/version.rb
|
80
|
+
- target/release/pacer.parallel-0.1.0-SNAPSHOT-standalone.jar
|
81
|
+
homepage: http://xnlogic.com
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- src/ruby
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.0.3
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: With the magic of Clojure's core.async
|
105
|
+
test_files: []
|