miner_mover 0.1.0.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 +4 -4
- data/README.md +132 -43
- data/Rakefile +23 -7
- data/VERSION +1 -1
- data/demo/process_socket.rb +1 -1
- data/lib/miner_mover/timer.rb +8 -8
- data/lib/miner_mover/worker.rb +38 -30
- data/lib/miner_mover.rb +8 -6
- data/miner_mover.gemspec +3 -14
- metadata +4 -78
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6d1e4d4ee9ab3ff3dedcd283b94f1c089dd6478657f215d0903a18bcbaa576f
|
4
|
+
data.tar.gz: b0d0a6fc768ede45676fa68545379e915d98e9c9f8d6416c48b7bd564b8b09fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3f7e4cffe3a1bc9805097a11f6490a7de4d64daa5c893e3341b569e89296d8dde97185a89f6cd5eabbcb4d9f1156d41c913fa33365601a6bb9cdacb4d8fbf6f
|
7
|
+
data.tar.gz: ae1292dfb2249203ad53a0860900dc49b6b46cd618f586fae8fa549700195448824d29347fb19460ff191164420113c687711a8dbbf1b101b71f9154395824b9
|
data/README.md
CHANGED
@@ -18,7 +18,7 @@ results as well. Ore is gathered at each depth; either a fixed amount or
|
|
18
18
|
randomized, based on depth. The amount of time spent mining each level is
|
19
19
|
independent and may be randomized.
|
20
20
|
|
21
|
-
https://github.com/rickhull/miner_mover/blob/
|
21
|
+
https://github.com/rickhull/miner_mover/blob/4f2a62f6d77316e780c7c13248698d4c57bb392e/lib/miner_mover/worker.rb#L96-L104
|
22
22
|
|
23
23
|
In this case, miners are rewarded by calculating `fibonacci(depth)`, using
|
24
24
|
classic, inefficient fibonacci.
|
@@ -31,7 +31,7 @@ A mover has a batch size, say 10. As the mover accumulates ore over time,
|
|
31
31
|
once the batch size is reached, the mover delivers the ore to the destination.
|
32
32
|
Larger batches take longer. The delivery time can be randomized.
|
33
33
|
|
34
|
-
https://github.com/rickhull/miner_mover/blob/
|
34
|
+
https://github.com/rickhull/miner_mover/blob/4f2a62f6d77316e780c7c13248698d4c57bb392e/lib/miner_mover/worker.rb#L152-L183
|
35
35
|
|
36
36
|
The time and work spent delivering ore can be simulated three ways,
|
37
37
|
configured via `:work_type`
|
@@ -44,18 +44,22 @@ configured via `:work_type`
|
|
44
44
|
|
45
45
|
## Install
|
46
46
|
|
47
|
-
You'll want to use **Ruby 3.x** to make the most of Fibers.
|
47
|
+
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
|
54
|
-
* fiber_scheduler
|
55
52
|
|
56
|
-
`gem install
|
53
|
+
`gem install dotcfg`
|
54
|
+
|
55
|
+
#### Additionally
|
56
|
+
|
57
|
+
To use Fiber::Scheduler and kqueue / epoll / io_uring:
|
58
|
+
|
59
|
+
* fiber_scheduler
|
60
|
+
* io-event
|
57
61
|
|
58
|
-
`gem install
|
62
|
+
`gem install fiber_scheduler io-event`
|
59
63
|
|
60
64
|
### Clone
|
61
65
|
|
@@ -71,20 +75,21 @@ Try: `rake -T` to see available [Rake tasks](Rakefile)
|
|
71
75
|
```
|
72
76
|
$ rake -T
|
73
77
|
|
74
|
-
rake
|
75
|
-
rake
|
76
|
-
rake
|
77
|
-
rake
|
78
|
-
rake
|
79
|
-
rake
|
80
|
-
rake
|
81
|
-
rake
|
82
|
-
rake
|
83
|
-
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
|
84
87
|
rake test # Run tests
|
85
|
-
rake thread #
|
88
|
+
rake thread # Run demo/thread.rb
|
86
89
|
```
|
87
90
|
|
91
|
+
Try: `rake test`
|
92
|
+
|
88
93
|
## Rake Tasks
|
89
94
|
|
90
95
|
Included demonstration scripts can be executed via Rake tasks.
|
@@ -113,36 +118,76 @@ Rake tasks take care of `LOAD_PATH`, so the following is
|
|
113
118
|
|
114
119
|
## Exploration in `irb`
|
115
120
|
|
116
|
-
`$ irb -
|
121
|
+
`$ irb -I lib`
|
117
122
|
|
118
123
|
```
|
119
|
-
irb(main):001:0>
|
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):
|
130
|
+
irb(main):003:0> miner = Miner.new
|
123
131
|
=>
|
124
|
-
#<MinerMover::Miner:
|
132
|
+
#<MinerMover::Miner:0x00007fbee8a3a080
|
125
133
|
...
|
126
134
|
|
127
|
-
irb(main):
|
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:
|
137
|
+
#<MinerMover::Mover:0x00007fbee8a8a6c0
|
139
138
|
...
|
140
139
|
|
141
|
-
irb(main):
|
142
|
-
=>
|
143
|
-
|
144
|
-
|
145
|
-
=>
|
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
|
@@ -379,11 +464,15 @@ others. My favorites:
|
|
379
464
|
|
380
465
|
* `Process.fork` - when called with a block, the block is only executed in the
|
381
466
|
child subprocess
|
382
|
-
* `Process.spawn` - extensive options, nonblocking, call Process.wait(pid)
|
467
|
+
* `Process.spawn` - extensive options, nonblocking, call `Process.wait(pid)`
|
383
468
|
to get the result
|
384
|
-
* `Open3.popen3` - for access to STDIN
|
469
|
+
* `Open3.popen3` - for access to `STDIN` `STDOUT` `STDERR`
|
385
470
|
|
386
471
|
### IPC
|
387
472
|
|
388
|
-
* Pipes
|
389
|
-
|
473
|
+
* Pipes
|
474
|
+
- `IO.pipe` (streaming / bytes / unidirectional)
|
475
|
+
* Unix sockets
|
476
|
+
- `UNIXSocket.pair :RAW`
|
477
|
+
- `UNIXSocket.pair :DGRAM` (datagram / message / "like UDP")
|
478
|
+
- `UNIXSocket.pair :STREAM` (streaming / bytes / "like TCP")
|
data/Rakefile
CHANGED
@@ -1,27 +1,43 @@
|
|
1
|
-
|
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 "
|
14
|
-
task(name) {
|
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 "
|
30
|
+
desc "Run JVM compatible demos"
|
19
31
|
task jvm_demo: [:serial, :fiber, :thread]
|
20
32
|
|
21
|
-
desc "
|
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
|
+
0.1.2.1
|
data/demo/process_socket.rb
CHANGED
data/lib/miner_mover/timer.rb
CHANGED
@@ -44,22 +44,22 @@ module MinerMover
|
|
44
44
|
t.strftime "%Y-%m-%d %H:%M:%S.%L"
|
45
45
|
end
|
46
46
|
|
47
|
-
def restart(
|
48
|
-
@start =
|
47
|
+
def restart(f = Timer.now)
|
48
|
+
@start = f
|
49
49
|
self
|
50
50
|
end
|
51
51
|
alias_method :initialize, :restart
|
52
52
|
|
53
|
-
def elapsed(
|
54
|
-
|
53
|
+
def elapsed(f = Timer.now)
|
54
|
+
f - @start
|
55
55
|
end
|
56
56
|
|
57
|
-
def elapsed_ms(
|
58
|
-
elapsed(
|
57
|
+
def elapsed_ms(f = Timer.now)
|
58
|
+
elapsed(f) * 1000
|
59
59
|
end
|
60
60
|
|
61
|
-
def elapsed_display(
|
62
|
-
Timer.elapsed_display(elapsed_ms(
|
61
|
+
def elapsed_display(f = Timer.now)
|
62
|
+
Timer.elapsed_display(elapsed_ms(f))
|
63
63
|
end
|
64
64
|
alias_method :to_s, :elapsed_display
|
65
65
|
alias_method :inspect, :elapsed_display
|
data/lib/miner_mover/worker.rb
CHANGED
@@ -77,32 +77,36 @@ module MinerMover
|
|
77
77
|
class Miner < Worker
|
78
78
|
attr_accessor :depth, :partial_reward
|
79
79
|
|
80
|
-
def initialize(depth:
|
81
|
-
partial_reward:
|
80
|
+
def initialize(depth: 5,
|
81
|
+
partial_reward: false,
|
82
82
|
variance: 0,
|
83
83
|
logging: false,
|
84
84
|
debugging: false,
|
85
85
|
timer: nil)
|
86
86
|
@partial_reward = partial_reward
|
87
87
|
@depth = depth
|
88
|
-
super(variance: variance,
|
89
|
-
|
88
|
+
super(variance: variance, timer: timer,
|
89
|
+
logging: logging, debugging: debugging)
|
90
90
|
end
|
91
91
|
|
92
92
|
def state
|
93
93
|
super.merge(depth: @depth, partial_reward: @partial_reward)
|
94
94
|
end
|
95
95
|
|
96
|
+
# return an array of integers representing ore mined at each depth
|
97
|
+
def mine_ores(depth = @depth)
|
98
|
+
# every new depth is a new mining operation
|
99
|
+
Array.new(depth) { |d|
|
100
|
+
# mine ore by calculating fibonacci for that depth
|
101
|
+
mined = MinerMover.fib(self.varied(d).round)
|
102
|
+
@partial_reward ? rand(1 + mined) : mined
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
# wrap the above method with logging, timing, and summing
|
96
107
|
def mine_ore(depth = @depth)
|
97
108
|
log format("MINE Depth %i", depth)
|
98
|
-
ores, elapsed = Timer.elapsed {
|
99
|
-
# every new depth is a new mining operation
|
100
|
-
Array.new(depth) { |d|
|
101
|
-
# mine ore by calculating fibonacci for that depth
|
102
|
-
mined = MinerMover.fib self.varied(d).round
|
103
|
-
@partial_reward ? rand(1 + mined) : mined
|
104
|
-
}
|
105
|
-
}
|
109
|
+
ores, elapsed = Timer.elapsed { self.mine_ores(depth) }
|
106
110
|
total = ores.sum
|
107
111
|
log format("MIND %s %s (%.2f s)",
|
108
112
|
Ore.display(total), ores.inspect, elapsed)
|
@@ -124,8 +128,8 @@ module MinerMover
|
|
124
128
|
@rate = rate.to_f * Ore::BLOCK
|
125
129
|
@work_type = work_type
|
126
130
|
@batch, @batches, @ore_moved = 0, 0, 0
|
127
|
-
super(variance: variance,
|
128
|
-
|
131
|
+
super(variance: variance, timer: timer,
|
132
|
+
logging: logging, debugging: debugging)
|
129
133
|
end
|
130
134
|
|
131
135
|
def state
|
@@ -145,33 +149,37 @@ module MinerMover
|
|
145
149
|
].join(' | ')
|
146
150
|
end
|
147
151
|
|
148
|
-
|
149
|
-
|
152
|
+
# accept some ore for moving; just accumulate unless we have a full batch
|
153
|
+
def load_ore amount
|
154
|
+
log format("LOAD %s | %s", Ore.display(amount), self.status)
|
155
|
+
@batch += amount
|
150
156
|
move_batch if @batch >= @batch_size
|
151
|
-
log format("
|
157
|
+
log format("LDED %s | %s", Ore.display(amount), self.status)
|
152
158
|
@batch
|
153
159
|
end
|
154
160
|
|
155
|
-
|
156
|
-
MinerMover.work(duration, @work_type)
|
157
|
-
end
|
158
|
-
|
161
|
+
# return the amount moved
|
159
162
|
def move_batch
|
160
163
|
raise "unexpected batch: #{@batch}" if @batch <= 0
|
161
|
-
|
162
|
-
duration = self.varied(amt / @rate)
|
164
|
+
amount = [@batch, @batch_size].min
|
163
165
|
|
164
|
-
|
165
|
-
_, elapsed = Timer.elapsed { self.move(duration) }
|
166
|
-
log format("MOVD %s (%.2f s)", Ore.display(amt), elapsed)
|
166
|
+
self.move amount
|
167
167
|
|
168
168
|
# accounting
|
169
|
-
@ore_moved +=
|
170
|
-
@batch -=
|
169
|
+
@ore_moved += amount
|
170
|
+
@batch -= amount
|
171
171
|
@batches += 1
|
172
172
|
|
173
|
-
|
174
|
-
|
173
|
+
amount
|
174
|
+
end
|
175
|
+
|
176
|
+
# perform the work of moving the amount of ore
|
177
|
+
def move amount
|
178
|
+
duration = self.varied(amount / @rate)
|
179
|
+
log format("MOVE %s (%.2f s)", Ore.display(amount), duration)
|
180
|
+
_, elapsed = Timer.elapsed { MinerMover.work(duration, @work_type) }
|
181
|
+
log format("MOVD %s (%.2f s)", Ore.display(amount), elapsed)
|
182
|
+
self
|
175
183
|
end
|
176
184
|
end
|
177
185
|
end
|
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.
|
6
|
+
self.write(io, str + separator)
|
7
7
|
end
|
8
8
|
|
9
|
-
def self.
|
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
|
-
|
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 = "
|
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.
|
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.
|
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
|
-
|
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
|