sorta-parallel 0.1.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96d6441088d9b1c3bb231dedb38852bc1b93a23707dc166e457dde7667405cf0
4
- data.tar.gz: eabb6a5c0c9a5a654ff14f2ec5d9a12eacd8c1672dae32d49d86fa3d56044bb6
3
+ metadata.gz: 2bf3d65c13dd764223f1bf6946351ac43e3dced1307fa20666d7becb5635fa5e
4
+ data.tar.gz: 66a6deb857fa7de088072fd50c56b2e462d2a8ef3bc925809af2290a5c6d9fff
5
5
  SHA512:
6
- metadata.gz: 707fd1ddf2c16aadf35218b3de7a0b4b410cc7617749221e2b51a96c7f5b386bda838fb27b01cd8d655a3327d90fc3c8ab27e40e9e24793cc57b8d3b60ba723a
7
- data.tar.gz: bd5de548cf4a8996841b2d3b4bce116571d5a749ae2464267609c7bf91a787d39384a495d18c5e5057861dc7c2a683239f0a509a3b87aa29bb15f9d32dcf642e
6
+ metadata.gz: 821903ba653e62b1483518bfabe14b9aa378b97b74b0102f750e8753199cbfc3afdf77ea855f9552e4653bc353c276f838764c9c0fb65678f985ac8da259c0fc
7
+ data.tar.gz: 9520d14a8246416d24ac38331974050ed3e8f88a15115cd8fb52ee469f87b45caeb61adb90e63f73049de03b94042951967364fab16ec59cf54f8bcde1a4d7c9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sorta-parallel (0.1.0)
4
+ sorta-parallel (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -7,20 +7,32 @@ class IncrTask
7
7
  end
8
8
 
9
9
  r1 = Ractor.new(name: '1') do
10
- source = [1,2,3]
11
- Sorta::Parallel.map(source, IncrTask)
10
+ 5.times.map do |i|
11
+ Thread.new do
12
+ source = (i..10).to_a
13
+ result = Sorta::Parallel.map(source, IncrTask)
14
+
15
+ puts "ractor: #{Ractor.current.name}, thread: #{i} source: #{source.inspect}, result: #{result.inspect}"
16
+ end
17
+ end.each(&:join)
12
18
  end
13
19
 
14
20
  r2 = Ractor.new(name: '2') do
15
- source = [9,10,11]
16
- Sorta::Parallel.map(source, IncrTask)
21
+ 5.times.map do |i|
22
+ Thread.new do
23
+ source = ((100+i)..(100+10)).to_a
24
+ result = Sorta::Parallel.map(source, IncrTask)
25
+
26
+ puts "ractor: #{Ractor.current.name} thread: #{i} source: #{source.inspect}, result: #{result.inspect}"
27
+ end
28
+ end.each(&:join)
17
29
  end
18
30
 
19
31
  workers = [r1, r2]
32
+ loop do
33
+ break if workers.empty?
20
34
 
21
- while workers.any?
22
- ractor, msg = Ractor.select(*workers)
23
- puts "ractor ##{ractor.name}, result: #{msg.inspect}"
35
+ ractor, _ = Ractor.select(*workers)
24
36
  workers.delete(ractor)
25
37
  end
26
38
 
@@ -0,0 +1,16 @@
1
+ require_relative '../lib/sorta/parallel.rb'
2
+
3
+ class IncrTask
4
+ def call(num)
5
+ num + 1
6
+ end
7
+ end
8
+
9
+ 5.times.map do |i|
10
+ Thread.new do
11
+ source = (i..10).to_a
12
+ result = Sorta::Parallel.map(source, IncrTask)
13
+
14
+ puts "source: #{source.inspect}, result: #{result.inspect}"
15
+ end
16
+ end.each(&:join)
data/examples/simple.rb CHANGED
@@ -6,9 +6,7 @@ class IncrTask
6
6
  end
7
7
  end
8
8
 
9
- source = [1,2,3]
9
+ source = (1..10).to_a
10
10
  result = Sorta::Parallel.map(source, IncrTask)
11
11
 
12
12
  puts "source: #{source.inspect}, result: #{result.inspect}"
13
-
14
-
@@ -2,12 +2,12 @@ module Sorta
2
2
  module Parallel
3
3
  class Executor
4
4
  def initialize(source, task_klass)
5
- # Reactor.update_current_ractor!
5
+ Reactor.start!
6
6
 
7
7
  @source = source.dup
8
8
  @task_klass = task_klass
9
9
  @results = []
10
- @result_pipe = Ractor.new { loop { Ractor.yield(Ractor.receive) } }
10
+ @response_queue = Queue.new
11
11
  end
12
12
 
13
13
  def each!
@@ -17,19 +17,17 @@ module Sorta
17
17
 
18
18
  def map!
19
19
  @source.each_with_index do |item, i|
20
- pipe.send([@task_klass, @result_pipe, item, i])
20
+ Reactor.register([@task_klass, @response_queue, item, i])
21
21
  end
22
22
 
23
- results = @source.size.times.map { @result_pipe.take }
24
- raise 'oh no no no' if results.include?(Signals::Error)
23
+ @source.size.times do
24
+ @results << @response_queue.pop
25
+ end
25
26
 
26
- # sort by index
27
- results.sort_by(&:last).transpose.first
28
- end
27
+ raise 'oh no no no' if @results.include?(Signals::Error)
29
28
 
30
- def pipe
31
- # Ractor.current[:sorta_parallel_pipe]
32
- Reactor::PIPE
29
+ # sort by index
30
+ @results.sort_by(&:last).transpose.first
33
31
  end
34
32
  end
35
33
  end
@@ -2,11 +2,48 @@ require 'etc'
2
2
 
3
3
  module Sorta
4
4
  module Parallel
5
- # globalstate, EEEW!!!
6
5
  module Reactor
7
- PIPE = Ractor.new { loop { Ractor.yield(Ractor.receive) } }
8
- # TODO: get count from env or from something else
9
- WORKERS = Etc.nprocessors.times.map { Worker.new(PIPE) }.freeze
6
+ def self.request_pipe
7
+ Ractor.current[:request_pipe] ||= Ractor.new { loop { Ractor.yield(Ractor.receive) } }
8
+ end
9
+
10
+ def self.result_pipe
11
+ Ractor.current[:result_pipe] ||= Ractor.new { loop { Ractor.yield(Ractor.receive) } }
12
+ end
13
+
14
+ def self.workers
15
+ Ractor.current[:workers] ||= Etc.nprocessors.times.map { Worker.new(request_pipe) }.freeze
16
+ end
17
+
18
+ def self.queues
19
+ Ractor.current[:queues] ||= {}
20
+ end
21
+
22
+ def self.register(task)
23
+ queues[task[1].object_id] = task[1]
24
+ safe_task = task.dup
25
+ safe_task[1] = task[1].object_id
26
+ request_pipe << [safe_task, result_pipe]
27
+ end
28
+
29
+ def self.start!
30
+ request_pipe
31
+ result_pipe
32
+ workers
33
+
34
+ Ractor.current[:thread] ||=
35
+ Thread.new do
36
+ loop do
37
+ msg = result_pipe.take
38
+ result_queue = queues[msg[1]]
39
+ result_queue.push(msg)
40
+ rescue => e
41
+ puts e.message
42
+ puts e.backtrace.join("\n")
43
+ next
44
+ end
45
+ end
46
+ end
10
47
  end
11
48
  end
12
49
  end
@@ -1,5 +1,5 @@
1
1
  module Sorta
2
2
  module Parallel
3
- VERSION = "0.1.1"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -4,10 +4,8 @@ module Sorta
4
4
  def self.new(pipe)
5
5
  super(pipe) do |pipe|
6
6
  loop do
7
- task, result_pipe, data, index = pipe.take
8
- break if task.is_a?(Tasks::Quit)
9
-
10
- result_pipe.send([task.new.call(data), index], move: true)
7
+ (task, queue_id, data, index), result_pipe = pipe.take
8
+ result_pipe.send([task.new.call(data), queue_id, index], move: true)
11
9
  rescue
12
10
  result_pipe.send(Signals::Error.new, move: true)
13
11
  next
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorta-parallel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mihail Odebe
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-06-02 00:00:00.000000000 Z
11
+ date: 2021-06-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -28,6 +28,7 @@ files:
28
28
  - bin/console
29
29
  - bin/setup
30
30
  - examples/multiractor.rb
31
+ - examples/multithread.rb
31
32
  - examples/simple.rb
32
33
  - lib/sorta/parallel.rb
33
34
  - lib/sorta/parallel/executor.rb