miner_mover 0.1.1.1 → 0.1.2.1

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