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 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