eldritch 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 126e27cd07d65470ca6636e9fdee32863141f810
4
- data.tar.gz: df821431679824457c23f5970d779b907d9371c6
3
+ metadata.gz: dcbd51f156e97fa93b15dbf1ea64470460156f92
4
+ data.tar.gz: 6a4463349a3a657c8d528ea74a64d88f8321667a
5
5
  SHA512:
6
- metadata.gz: 4f8fe3201d12712f927af4e21a8939feaaf4221e293b43d3581a55376ead5ad364329cc7aba43ab4d8896338777e386630ea1b6f40309469f48d37b442f88e87
7
- data.tar.gz: 2130979b69b7099a626b06c9e88a9d3640f21c0bc4cdfde89b1d3b0b98f3230677a058b6d5a01dd522a2d5f772cbce7c27ee3c0d8a53c2684e91dfc393a6e6db
6
+ metadata.gz: 911a4fcdac54808756205139c1256c8b63dccd8bcab7c82df3bf27db03c41f3d91df673213b2c200d127516c8c75ff7fbe71f2449e507094032fffa77dc68de5
7
+ data.tar.gz: b95e77b84bc0458692fb09a150c1bba0c007f7971abfb0fb163b9383077a4704ab304eea5ea6ac1cdd2229913d859a0dba824e6c9ef19cb102e0d6961f2eba44
@@ -1,4 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 1.9.3
4
+ - 2.0.0
3
5
  - 2.1.0
4
6
  - 2.1.1
7
+ - jruby-19mode
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_. The problem with using jRuby, is that
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
- You will probably see a speed boost if your code does a lot of IO or anything that's blocking. In that case running on a
113
- single core is not that much of a hindrance, because most of the threads will be blocked and your code should run more
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
 
@@ -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)/})
@@ -0,0 +1,12 @@
1
+ class Thread
2
+ attr_writer :eldritch_group
3
+ attr_accessor :eldritch_task
4
+
5
+ def eldritch_group
6
+ @eldritch_group ||= Eldritch::NilGroup.new
7
+ end
8
+
9
+ def in_eldritch_group?
10
+ !eldritch_group.nil?
11
+ end
12
+ end
@@ -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.group
83
+ old = Thread.current.eldritch_group
80
84
 
81
85
  group = Group.new
82
- Thread.current.group = group
86
+ Thread.current.eldritch_group = group
83
87
 
84
88
  yield group
85
89
 
86
90
  group.wait_all
87
- Thread.current.group = old
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.group << task
103
+ Thread.current.eldritch_group << task
100
104
  task
101
105
  end
102
106
 
@@ -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.task]
15
+ @tasks - [Thread.current.eldritch_task]
18
16
  end
19
17
 
20
18
  def <<(task)
@@ -1,5 +1,5 @@
1
1
  require 'eldritch/version'
2
- require 'eldritch/refinements/thread'
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
@@ -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.task = self
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.task = nil
34
+ @thread.eldritch_task = nil
37
35
  end
38
36
 
39
37
  # The return value of the task
@@ -1,3 +1,3 @@
1
1
  module Eldritch
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -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(:group=).with(anything)
31
+ allow(Thread.current).to receive(:eldritch_group=).with(anything)
32
32
 
33
- expect(Thread.current).to receive(:group=).with(group)
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(:group).and_return(old_group)
51
+ allow(Thread.current).to receive(:eldritch_group).and_return(old_group)
52
52
 
53
53
  klass.together {}
54
54
 
55
- expect(Thread.current.group).to eql(old_group)
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(:group).and_return(group)
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
- async def foo; end
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
- async def foo; end
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
- async def foo(_,_,_); end
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
- async def foo; 42; end
152
+ def foo; 42; end
153
+ async :foo
150
154
  end
151
155
  instance = klass.new
152
156
 
@@ -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(:task).and_return(task)
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(:task).and_return(task)
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(:task).and_return(task)
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(:task).and_return(task)
118
+ allow(Thread.current).to receive(:eldritch_task).and_return(task)
119
119
 
120
120
  group << task
121
121
  group.interrupt
@@ -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(:task=).with(task)
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(:task=).with(nil)
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(:task=).with(nil)
69
+ expect(thread).to receive(:eldritch_task=).with(nil)
70
70
  task.value
71
71
  end
72
72
 
@@ -1,49 +1,45 @@
1
1
  require 'spec_helper'
2
- require 'eldritch/refinements/thread'
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
- # refinements don't work with #respond_to? and send, we have to check for errors
11
- expect{thread.group}.not_to raise_error
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
- # refinements don't work with #respond_to? and send, we have to check for errors
17
- expect{thread.task}.not_to raise_error
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.group = group
25
- expect(thread.group).to eql(group)
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.group).to be_a Eldritch::NilGroup
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.group = nil
36
- expect(thread.in_group?).to be_false
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.group = Eldritch::NilGroup.new
41
- expect(thread.in_group?).to be_false
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.group = 2
46
- expect(thread.in_group?).to be_true
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.1
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-24 00:00:00.000000000 Z
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: '2.1'
121
+ version: '0'
122
122
  required_rubygems_version: !ruby/object:Gem::Requirement
123
123
  requirements:
124
124
  - - ">="
@@ -1,16 +0,0 @@
1
- module Eldritch
2
- module Refinements
3
- refine Thread do
4
- attr_writer :group
5
- attr_accessor :task
6
-
7
- def group
8
- @group ||= Eldritch::NilGroup.new
9
- end
10
-
11
- def in_group?
12
- !group.nil?
13
- end
14
- end
15
- end
16
- end