eldritch 1.0.1 → 1.1.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 +4 -4
- data/.travis.yml +3 -0
- data/README.md +22 -5
- data/eldritch.gemspec +0 -3
- data/lib/eldritch/core_ext/thread.rb +12 -0
- data/lib/eldritch/dsl.rb +10 -6
- data/lib/eldritch/group.rb +1 -3
- data/lib/eldritch/safe.rb +2 -2
- data/lib/eldritch/task.rb +2 -4
- data/lib/eldritch/version.rb +1 -1
- data/spec/dsl_spec.rb +13 -9
- data/spec/group_spec.rb +4 -4
- data/spec/task_spec.rb +3 -3
- data/spec/thread_spec.rb +14 -18
- metadata +4 -4
- data/lib/eldritch/refinements/thread.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dcbd51f156e97fa93b15dbf1ea64470460156f92
|
4
|
+
data.tar.gz: 6a4463349a3a657c8d528ea74a64d88f8321667a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 911a4fcdac54808756205139c1256c8b63dccd8bcab7c82df3bf27db03c41f3d91df673213b2c200d127516c8c75ff7fbe71f2449e507094032fffa77dc68de5
|
7
|
+
data.tar.gz: b95e77b84bc0458692fb09a150c1bba0c007f7971abfb0fb163b9383077a4704ab304eea5ea6ac1cdd2229913d859a0dba824e6c9ef19cb102e0d6961f2eba44
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -33,6 +33,20 @@ send_email(some_email) # runs in the background
|
|
33
33
|
# ...
|
34
34
|
```
|
35
35
|
|
36
|
+
#### ruby 1.9.3 and ruby 2.0.0
|
37
|
+
|
38
|
+
For all versions of ruby before 2.1.0, you need to define async methods like so:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
def foo
|
42
|
+
# stuff
|
43
|
+
end
|
44
|
+
async :foo
|
45
|
+
```
|
46
|
+
|
47
|
+
Since ruby 2.1.0, def returns the name of the method defined as a symbol. This allows for the cleaner `async def foo`
|
48
|
+
syntax.
|
49
|
+
|
36
50
|
### async blocks
|
37
51
|
|
38
52
|
Async blocks are run concurrently.
|
@@ -106,12 +120,11 @@ MRI has this nasty little feature called a _GIL_ or _Global Interpreter Lock_. T
|
|
106
120
|
thread can run at a time. Let's say that you have 4 cores, running threaded code on MRI will only make use of 1 core.
|
107
121
|
Sometimes, you might not gain a speed boost if you make code parallel. This could the case even if theory says otherwise.
|
108
122
|
|
109
|
-
Not all ruby implementations use a _GIL_. For example, jRuby does not use a _GIL_.
|
110
|
-
this gem requires ruby >= 2.1.0 and jRuby only supports up to 1.9.3 (as of writing this).
|
123
|
+
Not all ruby implementations use a _GIL_. For example, jRuby does not use a _GIL_.
|
111
124
|
|
112
|
-
|
113
|
-
single core is not that much of a hindrance, because most of the threads will
|
114
|
-
often.
|
125
|
+
If your ruby implementation has a _GIL_, you will probably see a speed boost if your code does a lot of IO or anything
|
126
|
+
that's blocking. In that case running on a single core is not that much of a hindrance, because most of the threads will
|
127
|
+
be blocked and your code should run more often.
|
115
128
|
|
116
129
|
Running examples
|
117
130
|
----------------
|
@@ -121,6 +134,10 @@ this repository you need to add `lib/` to the include path.
|
|
121
134
|
|
122
135
|
$ ruby -Ilib examples/the_example.rb
|
123
136
|
|
137
|
+
Be aware that if you are running ruby < 2.1.0, some the examples may not work. All the examples that define async
|
138
|
+
methods with `async def something; end` will not work. This is because since ruby 2.1.0 def returns the name of the
|
139
|
+
method defined as a symbol.
|
140
|
+
|
124
141
|
Installation
|
125
142
|
------------
|
126
143
|
|
data/eldritch.gemspec
CHANGED
@@ -13,9 +13,6 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = 'https://github.com/beraboris/eldritch'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
|
-
# need refinements
|
17
|
-
spec.required_ruby_version = '>= 2.1'
|
18
|
-
|
19
16
|
spec.files = `git ls-files -z`.split("\x0")
|
20
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
data/lib/eldritch/dsl.rb
CHANGED
@@ -5,8 +5,6 @@ module Eldritch
|
|
5
5
|
# - {#together together blocks}
|
6
6
|
# - {#sync sync keyword}
|
7
7
|
module DSL
|
8
|
-
using Eldritch::Refinements
|
9
|
-
|
10
8
|
# Creates an asynchronous method or starts an async block
|
11
9
|
#
|
12
10
|
# If a block is passed, this will be an async block.
|
@@ -27,6 +25,12 @@ module Eldritch
|
|
27
25
|
#
|
28
26
|
# foo
|
29
27
|
# #=> <Task>
|
28
|
+
# If you are using ruby < 2.1.0, you will need to define async methods like so:
|
29
|
+
#
|
30
|
+
# def foo
|
31
|
+
# # will run in parallel
|
32
|
+
# end
|
33
|
+
# async :foo
|
30
34
|
#
|
31
35
|
# @param [Symbol] method the name of the async method.
|
32
36
|
# @return [Task] a task representing the async method or block
|
@@ -76,15 +80,15 @@ module Eldritch
|
|
76
80
|
# @yield [Group] group of async blocks/calls
|
77
81
|
# @see Group Group class
|
78
82
|
def together
|
79
|
-
old = Thread.current.
|
83
|
+
old = Thread.current.eldritch_group
|
80
84
|
|
81
85
|
group = Group.new
|
82
|
-
Thread.current.
|
86
|
+
Thread.current.eldritch_group = group
|
83
87
|
|
84
88
|
yield group
|
85
89
|
|
86
90
|
group.wait_all
|
87
|
-
Thread.current.
|
91
|
+
Thread.current.eldritch_group = old
|
88
92
|
end
|
89
93
|
|
90
94
|
private
|
@@ -96,7 +100,7 @@ module Eldritch
|
|
96
100
|
rescue InterruptedError
|
97
101
|
end
|
98
102
|
end
|
99
|
-
Thread.current.
|
103
|
+
Thread.current.eldritch_group << task
|
100
104
|
task
|
101
105
|
end
|
102
106
|
|
data/lib/eldritch/group.rb
CHANGED
@@ -4,8 +4,6 @@ module Eldritch
|
|
4
4
|
# Represents a group of {Task tasks} or {DSL#async async calls/block}.
|
5
5
|
# It is used to act upon all the tasks in the group.
|
6
6
|
class Group
|
7
|
-
using Eldritch::Refinements
|
8
|
-
|
9
7
|
def initialize
|
10
8
|
@tasks = []
|
11
9
|
@mutex = Mutex.new
|
@@ -14,7 +12,7 @@ module Eldritch
|
|
14
12
|
|
15
13
|
# @return [Array<Task>] the other async calls/blocks in the group
|
16
14
|
def others
|
17
|
-
@tasks - [Thread.current.
|
15
|
+
@tasks - [Thread.current.eldritch_task]
|
18
16
|
end
|
19
17
|
|
20
18
|
def <<(task)
|
data/lib/eldritch/safe.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'eldritch/version'
|
2
|
-
require 'eldritch/
|
2
|
+
require 'eldritch/core_ext/thread'
|
3
3
|
require 'eldritch/task'
|
4
4
|
require 'eldritch/dsl'
|
5
5
|
require 'eldritch/group'
|
@@ -20,6 +20,6 @@ module Eldritch
|
|
20
20
|
# extend Eldritch::DSL # for async method declaration
|
21
21
|
# end
|
22
22
|
def self.inject_dsl
|
23
|
-
Object.include Eldritch::DSL
|
23
|
+
Object.send :include, Eldritch::DSL
|
24
24
|
end
|
25
25
|
end
|
data/lib/eldritch/task.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Eldritch
|
2
2
|
# Runs a block in parallel and allows for interaction with said block
|
3
3
|
class Task
|
4
|
-
using Eldritch::Refinements
|
5
|
-
|
6
4
|
attr_writer :value
|
7
5
|
|
8
6
|
# @return [Thread] underlying ruby thread
|
@@ -27,13 +25,13 @@ module Eldritch
|
|
27
25
|
# task.start # calls the block in parallel
|
28
26
|
def start
|
29
27
|
@thread = Thread.new self, &@block
|
30
|
-
@thread.
|
28
|
+
@thread.eldritch_task = self
|
31
29
|
end
|
32
30
|
|
33
31
|
# Waits for the task to complete
|
34
32
|
def wait
|
35
33
|
@thread.join
|
36
|
-
@thread.
|
34
|
+
@thread.eldritch_task = nil
|
37
35
|
end
|
38
36
|
|
39
37
|
# The return value of the task
|
data/lib/eldritch/version.rb
CHANGED
data/spec/dsl_spec.rb
CHANGED
@@ -28,9 +28,9 @@ describe Eldritch::DSL do
|
|
28
28
|
it 'should set the current thread group' do
|
29
29
|
group = double('group').as_null_object
|
30
30
|
allow(Eldritch::Group).to receive(:new).and_return(group)
|
31
|
-
allow(Thread.current).to receive(:
|
31
|
+
allow(Thread.current).to receive(:eldritch_group=).with(anything)
|
32
32
|
|
33
|
-
expect(Thread.current).to receive(:
|
33
|
+
expect(Thread.current).to receive(:eldritch_group=).with(group)
|
34
34
|
|
35
35
|
klass.together {}
|
36
36
|
end
|
@@ -48,11 +48,11 @@ describe Eldritch::DSL do
|
|
48
48
|
group = double('group').as_null_object
|
49
49
|
old_group = double('old group').as_null_object
|
50
50
|
allow(Eldritch::Group).to receive(:new).and_return(group)
|
51
|
-
allow(Thread.current).to receive(:
|
51
|
+
allow(Thread.current).to receive(:eldritch_group).and_return(old_group)
|
52
52
|
|
53
53
|
klass.together {}
|
54
54
|
|
55
|
-
expect(Thread.current.
|
55
|
+
expect(Thread.current.eldritch_group).to eql(old_group)
|
56
56
|
end
|
57
57
|
|
58
58
|
it 'should yield it the new group' do
|
@@ -78,7 +78,7 @@ describe Eldritch::DSL do
|
|
78
78
|
call_me.call(task)
|
79
79
|
end
|
80
80
|
|
81
|
-
allow(Thread.current).to receive(:
|
81
|
+
allow(Thread.current).to receive(:eldritch_group).and_return(group)
|
82
82
|
end
|
83
83
|
|
84
84
|
context 'with 0 arguments' do
|
@@ -108,7 +108,8 @@ describe Eldritch::DSL do
|
|
108
108
|
context 'with 1 argument' do
|
109
109
|
before do
|
110
110
|
klass.class_eval do
|
111
|
-
|
111
|
+
def foo; end
|
112
|
+
async :foo
|
112
113
|
end
|
113
114
|
end
|
114
115
|
|
@@ -120,7 +121,8 @@ describe Eldritch::DSL do
|
|
120
121
|
expect(klass).to receive(:define_method).with(:foo)
|
121
122
|
|
122
123
|
klass.class_eval do
|
123
|
-
|
124
|
+
def foo; end
|
125
|
+
async :foo
|
124
126
|
end
|
125
127
|
end
|
126
128
|
|
@@ -134,7 +136,8 @@ describe Eldritch::DSL do
|
|
134
136
|
|
135
137
|
it 'should pass all arguments' do
|
136
138
|
klass.class_eval do
|
137
|
-
|
139
|
+
def foo(_,_,_); end
|
140
|
+
async :foo
|
138
141
|
end
|
139
142
|
instance = klass.new
|
140
143
|
expect(instance).to receive(:__async_foo).with(1,2,3)
|
@@ -146,7 +149,8 @@ describe Eldritch::DSL do
|
|
146
149
|
expect(task).to receive(:value=).with(42)
|
147
150
|
|
148
151
|
klass.class_eval do
|
149
|
-
|
152
|
+
def foo; 42; end
|
153
|
+
async :foo
|
150
154
|
end
|
151
155
|
instance = klass.new
|
152
156
|
|
data/spec/group_spec.rb
CHANGED
@@ -46,7 +46,7 @@ describe Eldritch::Group do
|
|
46
46
|
describe '#others' do
|
47
47
|
it 'should return an empty array when there is only one task' do
|
48
48
|
task = double('task').as_null_object
|
49
|
-
allow(Thread.current).to receive(:
|
49
|
+
allow(Thread.current).to receive(:eldritch_task).and_return(task)
|
50
50
|
|
51
51
|
group << task
|
52
52
|
|
@@ -56,7 +56,7 @@ describe Eldritch::Group do
|
|
56
56
|
|
57
57
|
it 'should return all the task except the current one' do
|
58
58
|
task = double('task').as_null_object
|
59
|
-
allow(Thread.current).to receive(:
|
59
|
+
allow(Thread.current).to receive(:eldritch_task).and_return(task)
|
60
60
|
other_task = double('other task').as_null_object
|
61
61
|
|
62
62
|
group << task
|
@@ -96,7 +96,7 @@ describe Eldritch::Group do
|
|
96
96
|
it 'should not call abort on current task' do
|
97
97
|
task = double('task').as_null_object
|
98
98
|
expect(task).not_to receive(:abort)
|
99
|
-
allow(Thread.current).to receive(:
|
99
|
+
allow(Thread.current).to receive(:eldritch_task).and_return(task)
|
100
100
|
|
101
101
|
group << task
|
102
102
|
group.abort
|
@@ -115,7 +115,7 @@ describe Eldritch::Group do
|
|
115
115
|
it 'should not call interrupt on current task' do
|
116
116
|
task = double('task').as_null_object
|
117
117
|
expect(task).not_to receive(:interrupt)
|
118
|
-
allow(Thread.current).to receive(:
|
118
|
+
allow(Thread.current).to receive(:eldritch_task).and_return(task)
|
119
119
|
|
120
120
|
group << task
|
121
121
|
group.interrupt
|
data/spec/task_spec.rb
CHANGED
@@ -33,7 +33,7 @@ describe Eldritch::Task do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'should set the thread task' do
|
36
|
-
expect(thread).to receive(:
|
36
|
+
expect(thread).to receive(:eldritch_task=).with(task)
|
37
37
|
|
38
38
|
task.start
|
39
39
|
end
|
@@ -50,7 +50,7 @@ describe Eldritch::Task do
|
|
50
50
|
it 'should set the thread task to nil' do
|
51
51
|
task.start
|
52
52
|
|
53
|
-
expect(thread).to receive(:
|
53
|
+
expect(thread).to receive(:eldritch_task=).with(nil)
|
54
54
|
task.wait
|
55
55
|
end
|
56
56
|
end
|
@@ -66,7 +66,7 @@ describe Eldritch::Task do
|
|
66
66
|
it 'should set the thread task to nil' do
|
67
67
|
task.start
|
68
68
|
|
69
|
-
expect(thread).to receive(:
|
69
|
+
expect(thread).to receive(:eldritch_task=).with(nil)
|
70
70
|
task.value
|
71
71
|
end
|
72
72
|
|
data/spec/thread_spec.rb
CHANGED
@@ -1,49 +1,45 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'eldritch/
|
3
|
-
|
4
|
-
using Eldritch::Refinements
|
2
|
+
require 'eldritch/core_ext/thread'
|
5
3
|
|
6
4
|
describe Thread do
|
7
5
|
let(:thread) { Thread.new {} }
|
8
6
|
|
9
7
|
it 'should have group accessor' do
|
10
|
-
|
11
|
-
expect
|
12
|
-
expect{thread.group = nil}.not_to raise_error
|
8
|
+
expect(thread).to respond_to(:eldritch_group)
|
9
|
+
expect(thread).to respond_to(:eldritch_group=)
|
13
10
|
end
|
14
11
|
|
15
12
|
it 'should have a task accessor' do
|
16
|
-
|
17
|
-
expect
|
18
|
-
expect{thread.task = nil}.not_to raise_error
|
13
|
+
expect(thread).to respond_to(:eldritch_task)
|
14
|
+
expect(thread).to respond_to(:eldritch_task=)
|
19
15
|
end
|
20
16
|
|
21
17
|
describe '#group' do
|
22
18
|
it 'should return the togther previously set' do
|
23
19
|
group = double('group')
|
24
|
-
thread.
|
25
|
-
expect(thread.
|
20
|
+
thread.eldritch_group = group
|
21
|
+
expect(thread.eldritch_group).to eql(group)
|
26
22
|
end
|
27
23
|
|
28
24
|
it 'should return a NilGroup when none are set' do
|
29
|
-
expect(thread.
|
25
|
+
expect(thread.eldritch_group).to be_a Eldritch::NilGroup
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
33
29
|
describe '#in_group?' do
|
34
30
|
it 'should be false when group is nil' do
|
35
|
-
thread.
|
36
|
-
expect(thread.
|
31
|
+
thread.eldritch_group = nil
|
32
|
+
expect(thread.in_eldritch_group?).to be_false
|
37
33
|
end
|
38
34
|
|
39
35
|
it 'should be false when group is a NilGroup' do
|
40
|
-
thread.
|
41
|
-
expect(thread.
|
36
|
+
thread.eldritch_group = Eldritch::NilGroup.new
|
37
|
+
expect(thread.in_eldritch_group?).to be_false
|
42
38
|
end
|
43
39
|
|
44
40
|
it 'should be true when group is set' do
|
45
|
-
thread.
|
46
|
-
expect(thread.
|
41
|
+
thread.eldritch_group = 2
|
42
|
+
expect(thread.in_eldritch_group?).to be_true
|
47
43
|
end
|
48
44
|
end
|
49
45
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eldritch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boris Bera
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-04-
|
12
|
+
date: 2014-04-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -93,10 +93,10 @@ files:
|
|
93
93
|
- examples/simple_async_method.rb
|
94
94
|
- examples/together_simple.rb
|
95
95
|
- lib/eldritch.rb
|
96
|
+
- lib/eldritch/core_ext/thread.rb
|
96
97
|
- lib/eldritch/dsl.rb
|
97
98
|
- lib/eldritch/group.rb
|
98
99
|
- lib/eldritch/interrupted_error.rb
|
99
|
-
- lib/eldritch/refinements/thread.rb
|
100
100
|
- lib/eldritch/safe.rb
|
101
101
|
- lib/eldritch/task.rb
|
102
102
|
- lib/eldritch/version.rb
|
@@ -118,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
118
|
requirements:
|
119
119
|
- - ">="
|
120
120
|
- !ruby/object:Gem::Version
|
121
|
-
version: '
|
121
|
+
version: '0'
|
122
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
123
|
requirements:
|
124
124
|
- - ">="
|