miner_mover 0.1.1.1 → 0.1.2.1

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
  SHA256:
3
- metadata.gz: 9e2daa3ba8e778e20c25e3a6363683b3163e1141f9438b53be890845acf5440e
4
- data.tar.gz: b72dc662be9c50caa281e087b3708c72a53aa5e593eeb053b59a0679238d568b
3
+ metadata.gz: d6d1e4d4ee9ab3ff3dedcd283b94f1c089dd6478657f215d0903a18bcbaa576f
4
+ data.tar.gz: b0d0a6fc768ede45676fa68545379e915d98e9c9f8d6416c48b7bd564b8b09fc
5
5
  SHA512:
6
- metadata.gz: 3203db4674a641c4a53ebed0cea4aaa445ef9e120ad582bc1cfcc787541ee53a8677eff1e4936429c4eaa72ef686ef97941a7a929d2d5db4e88a678684005962
7
- data.tar.gz: e0052a82fa40bcf19b3382ead683087e52f90e6065751a65ff9475aadd141beb0ebe098673acffe48784f90c672aa5990fe2c0e117a3db4bd1782252af7cec91
6
+ metadata.gz: a3f7e4cffe3a1bc9805097a11f6490a7de4d64daa5c893e3341b569e89296d8dde97185a89f6cd5eabbcb4d9f1156d41c913fa33365601a6bb9cdacb4d8fbf6f
7
+ data.tar.gz: ae1292dfb2249203ad53a0860900dc49b6b46cd618f586fae8fa549700195448824d29347fb19460ff191164420113c687711a8dbbf1b101b71f9154395824b9
data/README.md CHANGED
@@ -48,12 +48,18 @@ You'll want to use **Ruby 3.x** (CRuby) to make the most of Fibers.
48
48
 
49
49
  ### Dependencies
50
50
 
51
- * rake
52
- * minitest
53
51
  * dotcfg
52
+
53
+ `gem install dotcfg`
54
+
55
+ #### Additionally
56
+
57
+ To use Fiber::Scheduler and kqueue / epoll / io_uring:
58
+
54
59
  * fiber_scheduler
60
+ * io-event
55
61
 
56
- `gem install rake minitest dotcfg fiber_scheduler`
62
+ `gem install fiber_scheduler io-event`
57
63
 
58
64
  ### Clone
59
65
 
@@ -69,18 +75,17 @@ Try: `rake -T` to see available [Rake tasks](Rakefile)
69
75
  ```
70
76
  $ rake -T
71
77
 
72
- rake alt_demo # run all demos minus fiber_scheduler / ractor / process
73
- rake config # run demo/config
74
- rake default # rake test
75
- rake demo # run all demos
76
- rake fiber # run demo/fiber
77
- rake fiber_scheduler # run demo/fiber_scheduler
78
- rake process_pipe # run demo/process_pipe
79
- rake process_socket # run demo/process_socket
80
- rake ractor # run demo/ractor
81
- rake serial # run demo/serial
78
+ rake config # Run demo/config.rb
79
+ rake demo # Run all demos
80
+ rake fiber # Run demo/fiber.rb
81
+ rake fiber_scheduler # Run demo/fiber_scheduler.rb
82
+ rake jvm_demo # Run JVM compatible demos
83
+ rake process_pipe # Run demo/process_pipe.rb
84
+ rake process_socket # Run demo/process_socket.rb
85
+ rake ractor # Run demo/ractor.rb
86
+ rake serial # Run demo/serial.rb
82
87
  rake test # Run tests
83
- rake thread # run demo/thread
88
+ rake thread # Run demo/thread.rb
84
89
  ```
85
90
 
86
91
  Try: `rake test`
@@ -116,33 +121,73 @@ Rake tasks take care of `LOAD_PATH`, so the following is
116
121
  `$ irb -I lib`
117
122
 
118
123
  ```
119
- irb(main):001:0> include MinerMover
124
+ irb(main):001:0> require 'miner_mover/worker'
125
+ => true
126
+
127
+ irb(main):002:0> include MinerMover
120
128
  => Object
121
129
 
122
- irb(main):002:0> miner = Miner.new
130
+ irb(main):003:0> miner = Miner.new
123
131
  =>
124
- #<MinerMover::Miner:0x00007fdd649754e8
132
+ #<MinerMover::Miner:0x00007fbee8a3a080
125
133
  ...
126
134
 
127
- irb(main):003:0> miner.mine_ore
128
- => 0
129
-
130
- irb(main):004:0> miner.mine_ore 5
131
- => 3
132
-
133
- irb(main):005:0> miner.mine_ore 20
134
- => 6483
135
-
136
- irb(main):006:0> mover = Mover.new
135
+ irb(main):004:0> mover = Mover.new
137
136
  =>
138
- #<MinerMover::Mover:0x00007fdd64979930
137
+ #<MinerMover::Mover:0x00007fbee8a8a6c0
139
138
  ...
140
139
 
141
- irb(main):007:0> mover.load_ore 6483
142
- => 6483
143
-
144
- irb(main):008:0> mover.status
145
- => "Batch 6483 / 10M 0% | Moved 0x (0M)"
140
+ irb(main):005:0> miner.state
141
+ =>
142
+ {:id=>"00050720",
143
+ :logging=>false,
144
+ :debugging=>false,
145
+ :timer=>10200,
146
+ :variance=>0,
147
+ :depth=>5,
148
+ :partial_reward=>false}
149
+
150
+ irb(main):006:0> mover.state
151
+ =>
152
+ {:id=>"00057860",
153
+ :logging=>false,
154
+ :debugging=>false,
155
+ :timer=>10456,
156
+ :variance=>0,
157
+ :work_type=>:cpu,
158
+ :batch_size=>10000000,
159
+ :batch=>0,
160
+ :batches=>0,
161
+ :ore_moved=>0}
162
+
163
+ irb(main):007:0> miner.mine_ore
164
+ => 7
165
+
166
+ irb(main):008:0> mover.load_ore 7
167
+ => 7
168
+
169
+ irb(main):009:0> miner.state
170
+ =>
171
+ {:id=>"00050720",
172
+ :logging=>false,
173
+ :debugging=>false,
174
+ :timer=>28831,
175
+ :variance=>0,
176
+ :depth=>5,
177
+ :partial_reward=>false}
178
+
179
+ irb(main):010:0> mover.state
180
+ =>
181
+ {:id=>"00057860",
182
+ :logging=>false,
183
+ :debugging=>false,
184
+ :timer=>27959,
185
+ :variance=>0,
186
+ :work_type=>:cpu,
187
+ :batch_size=>10000000,
188
+ :batch=>7,
189
+ :batches=>0,
190
+ :ore_moved=>0}
146
191
  ```
147
192
 
148
193
  ## Included scripts
@@ -165,6 +210,46 @@ multiple miners or movers.
165
210
 
166
211
  Execute via e.g. `ruby -Ilib demo/thread.rb`
167
212
 
213
+ ### Approaches
214
+
215
+ #### [Serial](demo/serial.rb)
216
+
217
+ One miner, one mover. The miner mines to a depth, then loads the ore.
218
+ When the mover has a full batch, the batch is moved while the miner waits.
219
+
220
+ #### [Fibers](demo/fiber.rb)
221
+
222
+ Without a Fiber Scheduler, this just changes some organizational things.
223
+ Again, one miner, one mover. The mover has its own fiber, and the mining
224
+ fiber can pass ore to the moving fiber. There is no concurrency, so the
225
+ performance is roughly the same as before.
226
+
227
+ #### [Fiber Scheduler](demo/fiber_scheduler.rb)
228
+
229
+ TBD
230
+
231
+ #### [Threads](demo/thread.rb)
232
+
233
+ An array of mining threads and an array of moving threads.
234
+ A single shared queue for loading ore from miners to movers.
235
+ All threads contend for the same execution lock (GVL).
236
+
237
+ #### [Ractors](demo/ractor.rb)
238
+
239
+ Moving threads execute in their own ractor.
240
+ Mining threads contend against mining threads. Moving threads, likewise.
241
+
242
+ #### [Processes with pipes](demo/process_pipe.rb)
243
+
244
+ Similar to ractors, but using `Process.fork` for movers, using a pipe to send
245
+ ore from the parent mining process.
246
+
247
+ #### [Processes with sockets](demo/process_socket.rb)
248
+
249
+ As above, but with Unix sockets (*not* network sockets), using any of
250
+ `SOCK_STREAM` `SOCK_DGRAM` `SOCK_SEQPACKET` socket types.
251
+ In all cases, ore amounts are 4 bytes so the types behave roughly equivalently.
252
+
168
253
  # Multitasking
169
254
 
170
255
  *Multitasking* here means "the most general sense of performing several tasks
data/Rakefile CHANGED
@@ -1,27 +1,43 @@
1
- require 'rake/testtask'
1
+ #
2
+ # test task
3
+ #
2
4
 
5
+ require 'rake/testtask'
3
6
  Rake::TestTask.new :test do |t|
4
7
  t.pattern = "test/*.rb"
5
8
  t.warning = true
6
9
  end
7
-
8
- desc "rake test"
9
10
  task default: :test
10
11
 
12
+ #
13
+ # demo tasks
14
+ #
15
+
16
+ if ENV['RUBYOPT'].nil? or ENV['RUBYOPT'].empty?
17
+ flags = ['-I', File.join(__dir__, 'lib')]
18
+ else
19
+ flags = nil # subprocesses will have RUBYOPT
20
+ end
21
+
22
+ # create a rake task to run each script in demo/
11
23
  Dir['demo/*.rb'].each { |demo_path|
12
24
  name = File.basename(demo_path, '.rb')
13
- desc "run demo/#{name}"
14
- task(name) { sh "ruby -Ilib #{demo_path}" }
25
+ desc "Run #{demo_path}"
26
+ task(name) { ruby *flags, demo_path }
15
27
  }
16
28
 
17
29
  # jruby / truffleruby lack fiber_scheduler, Ractor, and Process#fork
18
- desc "run all demos minus fiber_scheduler / ractor / process"
30
+ desc "Run JVM compatible demos"
19
31
  task jvm_demo: [:serial, :fiber, :thread]
20
32
 
21
- desc "run all demos"
33
+ desc "Run all demos"
22
34
  task demo: [:serial, :fiber, :fiber_scheduler,
23
35
  :thread, :ractor, :process_pipe, :process_socket]
24
36
 
37
+ #
38
+ # release tasks
39
+ #
40
+
25
41
  begin
26
42
  require 'buildar'
27
43
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1.1
1
+ 0.1.2.1
@@ -15,7 +15,7 @@ Signal.trap("INT") {
15
15
  stop_mining = true
16
16
  }
17
17
 
18
- socktype = [:DGRAM, :STREAM, :RAW].sample
18
+ socktype = [:DGRAM, :STREAM, :SEQPACKET].sample
19
19
  run.log "SOCK #{socktype}"
20
20
  csock, psock = UNIXSocket.pair(socktype)
21
21
 
data/lib/miner_mover.rb CHANGED
@@ -3,20 +3,22 @@ module MinerMover
3
3
 
4
4
  # $/ is the default line separator: "\n"
5
5
  def self.puts(str, io = $stdout, separator = LINE_SEP)
6
- self.write_nonblock(io, str + separator)
6
+ self.write(io, str + separator)
7
7
  end
8
8
 
9
- def self.write_nonblock(io, str)
9
+ def self.write(io, str)
10
+ # nonblocking write attempt; ensure the full string is written
10
11
  begin
11
- # nonblocking write attempt; ensure the full string is written
12
- size = str.bytesize
13
12
  num_bytes = io.write_nonblock(str)
14
- # blocking write if nonblocking write comes up short
15
- io.write str.byteslice(num_bytes, size - num_bytes) if num_bytes < size
16
13
  rescue IO::WaitWritable, Errno::EINTR
17
14
  IO.select([], [io]) # wait until writable
18
15
  retry
19
16
  end
17
+ # blocking write if nonblocking write comes up short
18
+ if num_bytes < str.bytesize
19
+ io.write str.byteslice(num_bytes, str.bytesize - num_bytes)
20
+ end
21
+ nil
20
22
  end
21
23
 
22
24
  def self.log_fmt(timer, id, msg)
data/miner_mover.gemspec CHANGED
@@ -5,11 +5,11 @@ Gem::Specification.new do |s|
5
5
  s.description = <<EOF
6
6
  Fundamentally, we have a set of miners and a set of movers. A miner takes some amount of time to mine ore, which is given to a mover. When a mover has enough ore for a full batch, the delivery takes some amount of time before more ore can be loaded.
7
7
  EOF
8
- s.authors = ["Rick Hull"]
8
+ s.authors = ["Rick Hull"]
9
9
  s.homepage = "https://github.com/rickhull/miner_mover"
10
10
  s.license = "LGPL-3.0"
11
11
 
12
- s.required_ruby_version = "~> 2"
12
+ s.required_ruby_version = "> 2"
13
13
 
14
14
  s.version = File.read(File.join(__dir__, 'VERSION')).chomp
15
15
 
@@ -18,16 +18,5 @@ EOF
18
18
  s.files += Dir['test/**/*.rb']
19
19
  s.files += Dir['demo/**/*.rb']
20
20
 
21
- s.add_dependency "dotcfg", "~> 1.0"
22
-
23
- s.requirements << "For all features and best performance:"
24
- s.requirements << "gem install rake minitest fiber_scheduler"
25
- s.requirements << "For dev tools:"
26
- s.requirements << "gem install buildar flog flay"
27
-
28
- s.add_development_dependency "rake", "~> 13.0" # CVE-2020-8130
29
- s.add_development_dependency "minitest", "~> 5.0"
30
- s.add_development_dependency "buildar", "~> 3.0"
31
- s.add_development_dependency "flog", "~> 0"
32
- s.add_development_dependency "flay", "~> 0"
21
+ s.add_runtime_dependency "dotcfg", "~> 1.0"
33
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miner_mover
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1.1
4
+ version: 0.1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rick Hull
@@ -24,76 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '13.0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '13.0'
41
- - !ruby/object:Gem::Dependency
42
- name: minitest
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '5.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '5.0'
55
- - !ruby/object:Gem::Dependency
56
- name: buildar
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '3.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '3.0'
69
- - !ruby/object:Gem::Dependency
70
- name: flog
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: flay
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
27
  description: 'Fundamentally, we have a set of miners and a set of movers. A miner
98
28
  takes some amount of time to mine ore, which is given to a mover. When a mover has
99
29
  enough ore for a full batch, the delivery takes some amount of time before more
@@ -133,7 +63,7 @@ require_paths:
133
63
  - lib
134
64
  required_ruby_version: !ruby/object:Gem::Requirement
135
65
  requirements:
136
- - - "~>"
66
+ - - ">"
137
67
  - !ruby/object:Gem::Version
138
68
  version: '2'
139
69
  required_rubygems_version: !ruby/object:Gem::Requirement
@@ -141,12 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
71
  - - ">="
142
72
  - !ruby/object:Gem::Version
143
73
  version: '0'
144
- requirements:
145
- - 'For all features and best performance:'
146
- - gem install rake minitest fiber_scheduler
147
- - 'For dev tools:'
148
- - gem install buildar flog flay
149
- rubygems_version: 3.3.20
74
+ requirements: []
75
+ rubygems_version: 3.4.4
150
76
  signing_key:
151
77
  specification_version: 4
152
78
  summary: This project provides a basic concurrency problem useful for exploring different