celluloid-pmap 0.1.0 → 0.2.0
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/.travis.yml +3 -3
- data/README.md +42 -14
- data/celluloid-pmap.gemspec +3 -2
- data/lib/celluloid/pmap.rb +7 -3
- data/lib/celluloid/pmap/parallel_map_worker.rb +2 -2
- data/lib/celluloid/pmap/version.rb +1 -1
- data/spec/celluloid/pmap/parallel_map_worker_spec.rb +2 -2
- data/spec/celluloid/pmap_spec.rb +7 -0
- data/spec/support/benchmark_spec.rb +5 -3
- metadata +33 -33
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dd8a1f6f0315f3acd623701b984e804bb3f1d282
|
4
|
+
data.tar.gz: b352db781fc66bedf019e7e70eca037731a382fe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5221c5887556d0530b0a8c3f5bf13f9f5c17d49fd8a970899d19eff295d62a73f8978d7c64829e6b29638597869a30e198c6e5bd891c25b3b191ac2b684c230e
|
7
|
+
data.tar.gz: 30c8b6a0c707ebb2f1f919d2146c6a1b3095055b513ea283f0de7bf873f483325e294486cc563bfcfb996ab4c28b03251338d040c81d6c1dcb80be81173ae991
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Celluloid::Pmap
|
2
2
|
|
3
|
-
[](https://travis-ci.org/jwo/celluloid-pmap)
|
3
|
+
[](https://travis-ci.org/jwo/celluloid-pmap)
|
4
|
+
[](https://codeclimate.com/github/jwo/celluloid-pmap)
|
4
5
|
|
5
6
|
Parallel Mapping using Celluloid
|
6
7
|
|
@@ -17,6 +18,19 @@ The pmap will return an array of values when all of the Futures have completed a
|
|
17
18
|
|
18
19
|
The pool can help to make sure you don't exceed your connection resources. A common use case for this is in Rails, you can easily exceed the default ActiveRecord connection size.
|
19
20
|
|
21
|
+
### Use with ActiveRecord
|
22
|
+
|
23
|
+
Some users have reported connection leaking with using ActiveRecord objects in a
|
24
|
+
pmap. You can reuse a connection with this code below. You can read the backstory
|
25
|
+
on the [decision to not include an AR dependency](https://github.com/jwo/celluloid-pmap/pull/2).
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
users.pmap(4) do |user|
|
29
|
+
ActiveRecord::Base.connection_pool.with_connection { user.do_hefty_stuff! }
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
|
20
34
|
### Inspiration for this code
|
21
35
|
|
22
36
|
Tony Arcieri created [celluloid](http://celluloid.io/), and the [simple_pmap example](https://github.com/celluloid/celluloid/blob/master/examples/simple_pmap.rb) from which this codebase started
|
@@ -31,11 +45,11 @@ Because I've been implementing the same initializer code in every project I've w
|
|
31
45
|
|
32
46
|
### What rubies will this run on?
|
33
47
|
|
34
|
-
*
|
35
|
-
*
|
48
|
+
* 2.0.0
|
49
|
+
* 2.1.3
|
50
|
+
* 2.2.0
|
36
51
|
* jruby-19mode
|
37
52
|
* jruby-head
|
38
|
-
* rbx-19mode
|
39
53
|
|
40
54
|
|
41
55
|
## Installation
|
@@ -52,16 +66,20 @@ Default usage will execute in parallel. Simply pass a block to an Enumerable
|
|
52
66
|
```
|
53
67
|
puts "You'll see the puts happen instantly, and the sleep in parallel"
|
54
68
|
|
55
|
-
[55,65,75,85].pmap{|
|
56
|
-
|
69
|
+
[55,65,75,85].pmap{|limit| puts "I can't drive #{limit}!"; sleep(rand)}
|
70
|
+
```
|
71
|
+
|
72
|
+
Or something more real-world?
|
57
73
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
74
|
+
```
|
75
|
+
User.active.all.pmap do |user|
|
76
|
+
stripe_user = Stripe::Customer.retrieve user.stripe_customer_token
|
77
|
+
user.invoices = BuildsInvoicesFromStripeUser.build(stripe_user)
|
78
|
+
user.save
|
79
|
+
end
|
62
80
|
```
|
63
81
|
|
64
|
-
Problem: When using with ActiveRecord, you can quickly run out of connections.
|
82
|
+
Problem: When using with ActiveRecord, you can quickly run out of connections.
|
65
83
|
Answer: Specify the max number of threads (actors) to create at once!
|
66
84
|
|
67
85
|
```
|
@@ -76,15 +94,21 @@ puts [1,2,3].pmap(2){|speed_limit| puts Time.now.tap { sleep(3) }}
|
|
76
94
|
|
77
95
|
We default pmap's threads to the number of Celluloid cores in the system.
|
78
96
|
|
79
|
-
|
97
|
+
### When should you use pmap over Sidekiq or Actors?
|
98
|
+
|
99
|
+
When you need the response right away. (well, right away in the workflow sense). This is crazy good in IRB too. Destroying multiple records in parallel is nice.
|
100
|
+
|
101
|
+
### When will this help performance?
|
80
102
|
|
81
103
|
* When the blocks are IO bound (like database or web queries)
|
82
104
|
* When you're running JRuby or Rubinius
|
83
105
|
* When you're running C Extensions
|
84
106
|
|
85
|
-
|
107
|
+
### So what will this not speed things up?
|
86
108
|
|
87
|
-
* Pure math or ruby computations
|
109
|
+
* Pure math or ruby computations*
|
110
|
+
|
111
|
+
\*except if you're on JRuby or Rubinius, where this will still speed those along quite nicely.
|
88
112
|
|
89
113
|
## Image Credit
|
90
114
|
|
@@ -94,6 +118,10 @@ Universe," AND "She-Ra: Princess of Power" are copyright Mattel.
|
|
94
118
|
|
95
119
|
More information on He-Man can be found at the unspeakably wow site: http://castlegrayskull.org
|
96
120
|
|
121
|
+
## Contributors
|
122
|
+
|
123
|
+
* [Jason Voegele](https://github.com/jvoegele)
|
124
|
+
|
97
125
|
## Contributing
|
98
126
|
|
99
127
|
1. Fork it
|
data/celluloid-pmap.gemspec
CHANGED
@@ -18,8 +18,9 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.add_dependency('celluloid', '~> 0.
|
21
|
+
gem.add_dependency('celluloid', '~> 0.16')
|
22
22
|
|
23
23
|
gem.add_development_dependency "rake"
|
24
|
-
gem.add_development_dependency "rspec"
|
24
|
+
gem.add_development_dependency "rspec", "2.99"
|
25
|
+
gem.add_development_dependency "pry"
|
25
26
|
end
|
data/lib/celluloid/pmap.rb
CHANGED
@@ -8,9 +8,13 @@ module Celluloid
|
|
8
8
|
def self.included(base)
|
9
9
|
base.class_eval do
|
10
10
|
|
11
|
-
def pmap(
|
12
|
-
pool =
|
13
|
-
|
11
|
+
def pmap(pool_or_size=Celluloid.cores, &block)
|
12
|
+
pool = if pool_or_size.class.ancestors.include?(Celluloid::PoolManager)
|
13
|
+
pool_or_size
|
14
|
+
else
|
15
|
+
Pmap::ParallelMapWorker.pool(size: pool_or_size)
|
16
|
+
end
|
17
|
+
futures = map { |elem| pool.future(:yielder, elem, block) }
|
14
18
|
futures.map { |future| future.value }
|
15
19
|
end
|
16
20
|
|
@@ -3,12 +3,12 @@ require 'celluloid/pmap/parallel_map_worker'
|
|
3
3
|
describe Celluloid::Pmap::ParallelMapWorker do
|
4
4
|
|
5
5
|
it "should execute the block we send" do
|
6
|
-
result = subject.yielder { 6 + 3 }
|
6
|
+
result = subject.yielder(proc { 6 + 3 })
|
7
7
|
result.should eq(9)
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should send in the argument to the block" do
|
11
|
-
result = subject.yielder(6) {
|
11
|
+
result = subject.yielder(6, ->(e) { e + 3 })
|
12
12
|
result.should eq(9)
|
13
13
|
end
|
14
14
|
end
|
data/spec/celluloid/pmap_spec.rb
CHANGED
@@ -40,6 +40,13 @@ describe Celluloid::Pmap do
|
|
40
40
|
}.to take_approximately(1).seconds
|
41
41
|
end
|
42
42
|
|
43
|
+
let(:pool) { Celluloid::Pmap::ParallelMapWorker.pool(size: 10) }
|
44
|
+
it 'can reuse an existing thread pool' do
|
45
|
+
expect {
|
46
|
+
[1,2,3,4,5,6].pmap(pool) {|x| x; sleep(1) }
|
47
|
+
}.to take_approximately(1).seconds
|
48
|
+
end
|
49
|
+
|
43
50
|
it 'should be included in enumerable' do
|
44
51
|
Enumerable.ancestors.should include(Celluloid::Pmap)
|
45
52
|
end
|
@@ -1,15 +1,17 @@
|
|
1
1
|
require 'benchmark'
|
2
2
|
|
3
|
-
RSpec::Matchers.define :take_approximately do |
|
3
|
+
RSpec::Matchers.define :take_approximately do |expected|
|
4
4
|
chain :seconds do; end
|
5
5
|
|
6
6
|
match do |block|
|
7
7
|
@elapsed = Benchmark.realtime do
|
8
8
|
block.call
|
9
9
|
end
|
10
|
-
@elapsed.should be_within(0.2).of(
|
10
|
+
@elapsed.should be_within(0.2).of(expected)
|
11
11
|
end
|
12
12
|
|
13
|
+
supports_block_expectations if respond_to? :supports_block_expectations
|
14
|
+
|
13
15
|
failure_message_for_should do |actual|
|
14
16
|
"expected block to take about #{expected} seconds, but took #{@elapsed}"
|
15
17
|
end
|
@@ -19,7 +21,7 @@ RSpec::Matchers.define :take_approximately do |n|
|
|
19
21
|
end
|
20
22
|
|
21
23
|
description do
|
22
|
-
"take approximately #{
|
24
|
+
"take approximately #{expected} seconds to execute"
|
23
25
|
end
|
24
26
|
|
25
27
|
end
|
metadata
CHANGED
@@ -1,62 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: celluloid-pmap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Jesse Wolgamott
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2015-03-31 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: celluloid
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version: '0.
|
19
|
+
version: '0.16'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: '0.
|
26
|
+
version: '0.16'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rspec
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.99'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.99'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
52
60
|
- !ruby/object:Gem::Version
|
53
61
|
version: '0'
|
54
62
|
type: :development
|
55
63
|
prerelease: false
|
56
64
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
65
|
requirements:
|
59
|
-
- -
|
66
|
+
- - ">="
|
60
67
|
- !ruby/object:Gem::Version
|
61
68
|
version: '0'
|
62
69
|
description: Easy Parallel Executing using Celluloid
|
@@ -66,9 +73,9 @@ executables: []
|
|
66
73
|
extensions: []
|
67
74
|
extra_rdoc_files: []
|
68
75
|
files:
|
69
|
-
- .gitignore
|
70
|
-
- .rspec
|
71
|
-
- .travis.yml
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".travis.yml"
|
72
79
|
- Gemfile
|
73
80
|
- LICENSE.txt
|
74
81
|
- README.md
|
@@ -84,34 +91,27 @@ files:
|
|
84
91
|
homepage: https://github.com/jwo/celluloid-pmap
|
85
92
|
licenses:
|
86
93
|
- MIT
|
94
|
+
metadata: {}
|
87
95
|
post_install_message:
|
88
96
|
rdoc_options: []
|
89
97
|
require_paths:
|
90
98
|
- lib
|
91
99
|
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
-
none: false
|
93
100
|
requirements:
|
94
|
-
- -
|
101
|
+
- - ">="
|
95
102
|
- !ruby/object:Gem::Version
|
96
103
|
version: '0'
|
97
|
-
segments:
|
98
|
-
- 0
|
99
|
-
hash: 1634678292580827716
|
100
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
-
none: false
|
102
105
|
requirements:
|
103
|
-
- -
|
106
|
+
- - ">="
|
104
107
|
- !ruby/object:Gem::Version
|
105
108
|
version: '0'
|
106
|
-
segments:
|
107
|
-
- 0
|
108
|
-
hash: 1634678292580827716
|
109
109
|
requirements: []
|
110
110
|
rubyforge_project:
|
111
|
-
rubygems_version:
|
111
|
+
rubygems_version: 2.4.5
|
112
112
|
signing_key:
|
113
|
-
specification_version:
|
114
|
-
summary:
|
113
|
+
specification_version: 4
|
114
|
+
summary: 'Celluloid Futures are wicked sweet, and when combined with a #pmap implementation
|
115
115
|
AND a supervisor to keep the max threads down, you can be wicked sweet too!'
|
116
116
|
test_files:
|
117
117
|
- spec/celluloid/pmap/parallel_map_worker_spec.rb
|