miner_mover 0.0.0.4 → 0.1.1.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 +88 -16
- data/Rakefile +17 -2
- data/VERSION +1 -1
- data/demo/fiber.rb +11 -17
- data/demo/fiber_scheduler.rb +13 -20
- data/demo/{process.rb → process_pipe.rb} +37 -38
- data/demo/process_socket.rb +111 -0
- data/demo/ractor.rb +10 -28
- data/demo/serial.rb +8 -15
- data/demo/thread.rb +11 -21
- data/lib/miner_mover/config.rb +6 -3
- data/lib/miner_mover/run.rb +25 -8
- data/lib/miner_mover/timer.rb +67 -0
- data/lib/miner_mover/worker.rb +58 -37
- data/lib/miner_mover.rb +47 -3
- data/miner_mover.gemspec +7 -4
- metadata +15 -37
data/demo/serial.rb
CHANGED
@@ -2,39 +2,32 @@ require 'miner_mover/run'
|
|
2
2
|
|
3
3
|
include MinerMover
|
4
4
|
|
5
|
-
run = Run.new.cfg_banner!(duration: 1)
|
6
|
-
run.
|
7
|
-
run.log "Starting"
|
5
|
+
run = Run.new.cfg_banner!(duration: 1).start!
|
6
|
+
run.timestamp!
|
7
|
+
run.log "Starting #{__FILE__}"
|
8
8
|
|
9
9
|
stop_mining = false
|
10
10
|
Signal.trap("INT") {
|
11
|
-
run.
|
11
|
+
run.timestamp!
|
12
12
|
run.log " *** SIGINT *** Stop Mining"
|
13
13
|
stop_mining = true
|
14
14
|
}
|
15
15
|
|
16
|
-
# system 'cpulimit', "--pid=#{Process.pid}", '--limit=1', '--background'
|
17
|
-
|
18
16
|
miner = run.new_miner
|
19
17
|
run.log "MINE Mining operation initialized [ctrl-c] to stop"
|
20
18
|
|
21
19
|
mover = run.new_mover
|
22
20
|
run.log "MOVE Moving operation initialized"
|
23
|
-
|
24
21
|
ore_mined = 0
|
25
22
|
|
26
|
-
|
27
|
-
while !stop_mining
|
28
|
-
# mine the ore
|
23
|
+
while !stop_mining # SIGINT will trigger stop_mining = true
|
29
24
|
ore = miner.mine_ore
|
30
25
|
ore_mined += ore
|
31
|
-
|
32
|
-
# load (and possibly move) the ore
|
33
|
-
mover.load_ore ore if ore > 0
|
26
|
+
mover.load_ore ore if ore > 0 # move_batch happens when a batch is full
|
34
27
|
|
35
28
|
# stop mining after a while
|
36
29
|
if run.time_limit? or run.ore_limit?(ore_mined)
|
37
|
-
run.
|
30
|
+
run.timestamp!
|
38
31
|
miner.log format("Mining limit reached: %s", Ore.display(ore_mined))
|
39
32
|
stop_mining = true
|
40
33
|
end
|
@@ -47,4 +40,4 @@ run.log "QUIT #{mover.status}"
|
|
47
40
|
ore_moved = mover.ore_moved
|
48
41
|
run.log format("MINE %s mined (%i)", Ore.display(ore_mined), ore_mined)
|
49
42
|
run.log format("MOVE %s moved (%i)", Ore.display(ore_moved), ore_moved)
|
50
|
-
run.
|
43
|
+
run.timestamp!
|
data/demo/thread.rb
CHANGED
@@ -3,13 +3,13 @@ require 'thread'
|
|
3
3
|
|
4
4
|
include MinerMover
|
5
5
|
|
6
|
-
run = Run.new.cfg_banner!(duration: 1)
|
7
|
-
run.
|
8
|
-
run.log "Starting"
|
6
|
+
run = Run.new.cfg_banner!(duration: 1).start!
|
7
|
+
run.timestamp!
|
8
|
+
run.log "Starting #{__FILE__}"
|
9
9
|
|
10
10
|
stop_mining = false
|
11
11
|
Signal.trap("INT") {
|
12
|
-
run.
|
12
|
+
run.timestamp!
|
13
13
|
run.log " *** SIGINT *** Stop Mining"
|
14
14
|
stop_mining = true
|
15
15
|
}
|
@@ -24,16 +24,11 @@ movers = Array.new(run.num_movers) { |i|
|
|
24
24
|
m = run.new_mover
|
25
25
|
run.log "MOVE Mover #{i} started"
|
26
26
|
|
27
|
+
# movers pull from the queue, load the ore, and move it
|
27
28
|
loop {
|
28
|
-
# a mover picks up mined ore from the queue
|
29
|
-
run.debug && m.log("POP ")
|
30
29
|
ore = queue.pop
|
31
|
-
run.debug && m.log("POPD #{ore}")
|
32
|
-
|
33
30
|
break if ore == :quit
|
34
|
-
|
35
|
-
# load (and possibly move) the ore
|
36
|
-
m.load_ore ore
|
31
|
+
m.load_ore ore # moving of ore possibly happens here (on a full batch)
|
37
32
|
}
|
38
33
|
|
39
34
|
# move any remaining ore and quit
|
@@ -45,6 +40,7 @@ movers = Array.new(run.num_movers) { |i|
|
|
45
40
|
|
46
41
|
|
47
42
|
run.log "MINE Mining operation started [ctrl-c] to stop"
|
43
|
+
|
48
44
|
# store the miner threads in an array
|
49
45
|
miners = Array.new(run.num_miners) { |i|
|
50
46
|
Thread.new {
|
@@ -55,19 +51,12 @@ miners = Array.new(run.num_miners) { |i|
|
|
55
51
|
# miners wait for the SIGINT signal to quit
|
56
52
|
while !stop_mining
|
57
53
|
ore = m.mine_ore
|
58
|
-
|
59
|
-
# send any ore mined to the movers
|
60
|
-
if ore > 0
|
61
|
-
run.debug && m.log("PUSH #{ore}")
|
62
|
-
queue.push ore
|
63
|
-
run.debug && m.log("PSHD #{ore}")
|
64
|
-
end
|
65
|
-
|
66
54
|
ore_mined += ore
|
55
|
+
queue.push ore if ore > 0 # send any ore mined to the movers
|
67
56
|
|
68
57
|
# stop mining after a while
|
69
58
|
if run.time_limit? or run.ore_limit?(ore_mined)
|
70
|
-
run.
|
59
|
+
run.timestamp!
|
71
60
|
m.log format("Mining limit reached: %s", Ore.display(ore_mined))
|
72
61
|
stop_mining = true
|
73
62
|
end
|
@@ -86,6 +75,7 @@ run.log format("MINE %s mined (%i)", Ore.display(ore_mined), ore_mined)
|
|
86
75
|
# tell all the movers to quit; gather their results
|
87
76
|
run.num_movers.times { queue.push :quit }
|
88
77
|
|
78
|
+
# wait for results
|
89
79
|
ore_moved = movers.map { |thr| thr.value.ore_moved }.sum
|
90
80
|
run.log format("MOVE %s moved (%i)", Ore.display(ore_moved), ore_moved)
|
91
|
-
run.
|
81
|
+
run.timestamp!
|
data/lib/miner_mover/config.rb
CHANGED
@@ -14,19 +14,22 @@ module MinerMover
|
|
14
14
|
time_limit: 5,
|
15
15
|
ore_limit: 100,
|
16
16
|
logging: true,
|
17
|
+
debugging: false,
|
17
18
|
}.freeze,
|
18
19
|
miner: {
|
19
20
|
depth: 30,
|
20
21
|
partial_reward: false,
|
21
22
|
variance: 0,
|
22
23
|
logging: true,
|
24
|
+
debugging: false,
|
23
25
|
}.freeze,
|
24
26
|
mover: {
|
25
|
-
batch_size:
|
26
|
-
rate:
|
27
|
+
batch_size: 8,
|
28
|
+
rate: 4,
|
27
29
|
work_type: :wait,
|
28
30
|
variance: 0,
|
29
31
|
logging: true,
|
32
|
+
debugging: false,
|
30
33
|
}.freeze,
|
31
34
|
}.freeze
|
32
35
|
|
@@ -60,7 +63,7 @@ module MinerMover
|
|
60
63
|
mover = cfg[:mover] || {}
|
61
64
|
main = cfg[:main] || {}
|
62
65
|
else
|
63
|
-
|
66
|
+
miner, mover, main = {}, {}, {}
|
64
67
|
end
|
65
68
|
{ miner: DEFAULT[:miner].merge(miner),
|
66
69
|
mover: DEFAULT[:mover].merge(mover),
|
data/lib/miner_mover/run.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'miner_mover/worker'
|
2
2
|
require 'miner_mover/config'
|
3
|
+
require 'miner_mover/timer'
|
3
4
|
|
4
5
|
module MinerMover
|
5
6
|
class Run
|
@@ -15,35 +16,47 @@ module MinerMover
|
|
15
16
|
f
|
16
17
|
end
|
17
18
|
|
18
|
-
attr_accessor :
|
19
|
+
attr_accessor :debugging, :logging
|
19
20
|
attr_accessor :num_miners, :num_movers
|
20
21
|
attr_accessor :cfg_file, :cfg, :miner, :mover, :timer
|
21
22
|
attr_accessor :time_limit, :ore_limit
|
22
23
|
|
23
|
-
def initialize(cfg_file: nil, timer: nil
|
24
|
+
def initialize(cfg_file: nil, timer: nil)
|
24
25
|
@cfg_file = self.class.cfg_file(cfg_file)
|
25
26
|
@cfg = Config.process @cfg_file
|
26
27
|
main = @cfg.fetch :main
|
27
28
|
@miner = @cfg.fetch :miner
|
28
29
|
@mover = @cfg.fetch :mover
|
29
30
|
|
31
|
+
@num_miners = main.fetch :num_miners
|
32
|
+
@num_movers = main.fetch :num_movers
|
33
|
+
|
30
34
|
@time_limit = main.fetch :time_limit
|
31
35
|
@ore_limit = main.fetch :ore_limit
|
32
36
|
@logging = main.fetch :logging
|
33
|
-
@
|
34
|
-
@num_movers = main.fetch :num_movers
|
37
|
+
@debugging = main.fetch :debugging
|
35
38
|
|
36
|
-
@timer = timer ||
|
37
|
-
@debug = debug
|
39
|
+
@timer = timer || Timer.new
|
38
40
|
end
|
39
41
|
|
40
42
|
def cfg_banner!(duration: 0)
|
41
|
-
|
43
|
+
MinerMover.puts "USING: #{@cfg_file}"
|
42
44
|
pp @cfg
|
43
45
|
sleep duration if duration > 0
|
44
46
|
self
|
45
47
|
end
|
46
48
|
|
49
|
+
def start!
|
50
|
+
@timer.restart
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def timestamp!
|
55
|
+
dash = '-' * 70
|
56
|
+
str = [dash, Timer.timestamp, dash].join(MinerMover::LINE_SEP)
|
57
|
+
MinerMover.puts str
|
58
|
+
end
|
59
|
+
|
47
60
|
def new_miner
|
48
61
|
Miner.new(**@miner)
|
49
62
|
end
|
@@ -61,7 +74,11 @@ module MinerMover
|
|
61
74
|
end
|
62
75
|
|
63
76
|
def log msg
|
64
|
-
@logging and
|
77
|
+
@logging and MinerMover.log @timer, ' (main) ', msg
|
78
|
+
end
|
79
|
+
|
80
|
+
def debug msg
|
81
|
+
@debugging and MinerMover.log @timer, '(debug) ', msg
|
65
82
|
end
|
66
83
|
end
|
67
84
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module MinerMover
|
2
|
+
class Timer
|
3
|
+
SECS_PER_MIN = 60
|
4
|
+
MINS_PER_HOUR = 60
|
5
|
+
SECS_PER_HOUR = SECS_PER_MIN * MINS_PER_HOUR
|
6
|
+
|
7
|
+
# returns a float representing seconds since epoch
|
8
|
+
if defined? Process::CLOCK_MONOTONIC
|
9
|
+
def self.now
|
10
|
+
Process.clock_gettime Process::CLOCK_MONOTONIC
|
11
|
+
end
|
12
|
+
else
|
13
|
+
def self.now
|
14
|
+
Time.now.to_f
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.since f
|
19
|
+
self.now - f
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.elapsed &work
|
23
|
+
f = self.now
|
24
|
+
return yield, self.since(f)
|
25
|
+
end
|
26
|
+
|
27
|
+
# HH::MM::SS.mmm.uuuuuuuu
|
28
|
+
def self.elapsed_display(elapsed_ms, show_micro: false)
|
29
|
+
elapsed_s, ms = elapsed_ms.divmod 1000
|
30
|
+
ms_only, ms_fraction = ms.round(8).divmod 1
|
31
|
+
|
32
|
+
h = elapsed_s / SECS_PER_HOUR
|
33
|
+
elapsed_s -= h * SECS_PER_HOUR
|
34
|
+
m, s = elapsed_s.divmod SECS_PER_MIN
|
35
|
+
|
36
|
+
hmsms = [[h, m, s].map { |i| i.to_s.rjust(2, '0') }.join(':'),
|
37
|
+
ms_only.to_s.rjust(3, '0')]
|
38
|
+
hmsms << (ms_fraction * 10 ** 8).round.to_s.ljust(8, '0') if show_micro
|
39
|
+
hmsms.join('.')
|
40
|
+
end
|
41
|
+
|
42
|
+
# YYYY-MM-DD HH::MM::SS.mmm
|
43
|
+
def self.timestamp(t = Time.now)
|
44
|
+
t.strftime "%Y-%m-%d %H:%M:%S.%L"
|
45
|
+
end
|
46
|
+
|
47
|
+
def restart(f = Timer.now)
|
48
|
+
@start = f
|
49
|
+
self
|
50
|
+
end
|
51
|
+
alias_method :initialize, :restart
|
52
|
+
|
53
|
+
def elapsed(f = Timer.now)
|
54
|
+
f - @start
|
55
|
+
end
|
56
|
+
|
57
|
+
def elapsed_ms(f = Timer.now)
|
58
|
+
elapsed(f) * 1000
|
59
|
+
end
|
60
|
+
|
61
|
+
def elapsed_display(f = Timer.now)
|
62
|
+
Timer.elapsed_display(elapsed_ms(f))
|
63
|
+
end
|
64
|
+
alias_method :to_s, :elapsed_display
|
65
|
+
alias_method :inspect, :elapsed_display
|
66
|
+
end
|
67
|
+
end
|
data/lib/miner_mover/worker.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
require 'miner_mover'
|
2
|
-
require '
|
3
|
-
require 'compsci/fibonacci'
|
2
|
+
require 'miner_mover/timer'
|
4
3
|
|
5
4
|
module MinerMover
|
6
|
-
def self.work(duration, type = :wait,
|
5
|
+
def self.work(duration, type = :wait, fib_target = 30)
|
7
6
|
case type
|
8
7
|
when :wait
|
9
8
|
sleep duration
|
10
9
|
duration
|
11
10
|
when :cpu
|
12
|
-
t =
|
13
|
-
|
11
|
+
t = Timer.new
|
12
|
+
self.fib(fib_target) while t.elapsed < duration
|
14
13
|
t.elapsed
|
15
14
|
when :instant
|
16
15
|
0
|
@@ -19,14 +18,19 @@ module MinerMover
|
|
19
18
|
end
|
20
19
|
end
|
21
20
|
|
21
|
+
def self.fib n
|
22
|
+
(n < 2) ? n : fib(n-1) + fib(n-2)
|
23
|
+
end
|
24
|
+
|
22
25
|
class Worker
|
23
|
-
attr_accessor :variance, :logging
|
26
|
+
attr_accessor :variance, :logging, :debugging
|
24
27
|
attr_reader :timer
|
25
28
|
|
26
|
-
def initialize(variance: 0, logging: false, timer: nil)
|
29
|
+
def initialize(variance: 0, logging: false, debugging: false, timer: nil)
|
27
30
|
@variance = variance
|
28
31
|
@logging = logging
|
29
|
-
@
|
32
|
+
@debugging = debugging
|
33
|
+
@timer = timer || Timer.new
|
30
34
|
end
|
31
35
|
|
32
36
|
def id
|
@@ -36,6 +40,7 @@ module MinerMover
|
|
36
40
|
def state
|
37
41
|
{ id: self.id,
|
38
42
|
logging: @logging,
|
43
|
+
debugging: @debugging,
|
39
44
|
timer: @timer.elapsed_ms.round,
|
40
45
|
variance: @variance }
|
41
46
|
end
|
@@ -45,7 +50,11 @@ module MinerMover
|
|
45
50
|
end
|
46
51
|
|
47
52
|
def log msg
|
48
|
-
@logging
|
53
|
+
@logging and MinerMover.log @timer, self.id, msg
|
54
|
+
end
|
55
|
+
|
56
|
+
def debug msg
|
57
|
+
@debugging and MinerMover.log @timer, self.id, msg
|
49
58
|
end
|
50
59
|
|
51
60
|
# 4 levels:
|
@@ -68,30 +77,36 @@ module MinerMover
|
|
68
77
|
class Miner < Worker
|
69
78
|
attr_accessor :depth, :partial_reward
|
70
79
|
|
71
|
-
def initialize(depth:
|
72
|
-
partial_reward:
|
80
|
+
def initialize(depth: 5,
|
81
|
+
partial_reward: false,
|
73
82
|
variance: 0,
|
74
83
|
logging: false,
|
84
|
+
debugging: false,
|
75
85
|
timer: nil)
|
76
86
|
@partial_reward = partial_reward
|
77
87
|
@depth = depth
|
78
|
-
super(variance: variance,
|
88
|
+
super(variance: variance, timer: timer,
|
89
|
+
logging: logging, debugging: debugging)
|
79
90
|
end
|
80
91
|
|
81
92
|
def state
|
82
93
|
super.merge(depth: @depth, partial_reward: @partial_reward)
|
83
94
|
end
|
84
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
|
85
107
|
def mine_ore(depth = @depth)
|
86
108
|
log format("MINE Depth %i", depth)
|
87
|
-
ores, elapsed =
|
88
|
-
# every new depth is a new mining operation
|
89
|
-
Array.new(depth) { |d|
|
90
|
-
# mine ore by calculating fibonacci for that depth
|
91
|
-
mined = CompSci::Fibonacci.classic(self.varied(d).round)
|
92
|
-
@partial_reward ? rand(1 + mined) : mined
|
93
|
-
}
|
94
|
-
}
|
109
|
+
ores, elapsed = Timer.elapsed { self.mine_ores(depth) }
|
95
110
|
total = ores.sum
|
96
111
|
log format("MIND %s %s (%.2f s)",
|
97
112
|
Ore.display(total), ores.inspect, elapsed)
|
@@ -107,12 +122,14 @@ module MinerMover
|
|
107
122
|
work_type: :cpu,
|
108
123
|
variance: 0,
|
109
124
|
logging: false,
|
125
|
+
debugging: false,
|
110
126
|
timer: nil)
|
111
127
|
@batch_size = batch_size * Ore::BLOCK
|
112
128
|
@rate = rate.to_f * Ore::BLOCK
|
113
129
|
@work_type = work_type
|
114
130
|
@batch, @batches, @ore_moved = 0, 0, 0
|
115
|
-
super(variance: variance,
|
131
|
+
super(variance: variance, timer: timer,
|
132
|
+
logging: logging, debugging: debugging)
|
116
133
|
end
|
117
134
|
|
118
135
|
def state
|
@@ -132,33 +149,37 @@ module MinerMover
|
|
132
149
|
].join(' | ')
|
133
150
|
end
|
134
151
|
|
135
|
-
|
136
|
-
|
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
|
137
156
|
move_batch if @batch >= @batch_size
|
138
|
-
log format("
|
157
|
+
log format("LDED %s | %s", Ore.display(amount), self.status)
|
139
158
|
@batch
|
140
159
|
end
|
141
160
|
|
142
|
-
|
143
|
-
MinerMover.work(duration, @work_type)
|
144
|
-
end
|
145
|
-
|
161
|
+
# return the amount moved
|
146
162
|
def move_batch
|
147
163
|
raise "unexpected batch: #{@batch}" if @batch <= 0
|
148
|
-
|
149
|
-
duration = self.varied(amt / @rate)
|
164
|
+
amount = [@batch, @batch_size].min
|
150
165
|
|
151
|
-
|
152
|
-
_, elapsed = CompSci::Timer.elapsed { self.move(duration) }
|
153
|
-
log format("MOVD %s (%.2f s)", Ore.display(amt), elapsed)
|
166
|
+
self.move amount
|
154
167
|
|
155
168
|
# accounting
|
156
|
-
@ore_moved +=
|
157
|
-
@batch -=
|
169
|
+
@ore_moved += amount
|
170
|
+
@batch -= amount
|
158
171
|
@batches += 1
|
159
172
|
|
160
|
-
|
161
|
-
|
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
|
162
183
|
end
|
163
184
|
end
|
164
185
|
end
|
data/lib/miner_mover.rb
CHANGED
@@ -1,7 +1,30 @@
|
|
1
1
|
module MinerMover
|
2
|
-
|
2
|
+
LINE_SEP = $/.freeze
|
3
|
+
|
4
|
+
# $/ is the default line separator: "\n"
|
5
|
+
def self.puts(str, io = $stdout, separator = LINE_SEP)
|
6
|
+
self.write_nonblock(io, str + separator)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.write_nonblock(io, str)
|
10
|
+
begin
|
11
|
+
# nonblocking write attempt; ensure the full string is written
|
12
|
+
size = str.bytesize
|
13
|
+
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
|
+
rescue IO::WaitWritable, Errno::EINTR
|
17
|
+
IO.select([], [io]) # wait until writable
|
18
|
+
retry
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
3
22
|
def self.log_fmt(timer, id, msg)
|
4
|
-
format("%s %s %s", timer
|
23
|
+
format("%s %s %s", timer, id, msg)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.log(timer, id, msg)
|
27
|
+
self.puts self.log_fmt(timer, id, msg)
|
5
28
|
end
|
6
29
|
|
7
30
|
# i +- 50% at squeeze 0
|
@@ -18,7 +41,28 @@ module MinerMover
|
|
18
41
|
|
19
42
|
# ore is handled in blocks of 1M
|
20
43
|
module Ore
|
21
|
-
BLOCK = 1_000_000
|
44
|
+
BLOCK = 1_000_000 # between fib(30) and fib(31)
|
45
|
+
WORD_LENGTH = 4 # bytes
|
46
|
+
WORD_MAX = 256 ** WORD_LENGTH # up to 4.3B ore
|
47
|
+
HEX_UNPACK = "H#{WORD_LENGTH * 2}" # 4 bytes is 8 hex digits
|
48
|
+
|
49
|
+
# return 4 bytes, unsigned 32 bit integer, network order
|
50
|
+
def self.encode(ore)
|
51
|
+
raise "WORD_MAX overflow: #{self.block(ore)}M ore" if ore > WORD_MAX
|
52
|
+
[ore].pack('N')
|
53
|
+
end
|
54
|
+
|
55
|
+
# return an integer from the first 4 bytes
|
56
|
+
def self.decode(word)
|
57
|
+
raise "unexpected size: #{word.bytesize}" unless word.bytesize == 4
|
58
|
+
word.unpack('N').first
|
59
|
+
end
|
60
|
+
|
61
|
+
# return "0x01020304" for "\x01\x02\x03\x04"
|
62
|
+
def self.hex(word)
|
63
|
+
raise "unexpected size: #{word.bytesize}" unless word.bytesize == 4
|
64
|
+
"0x" + word.unpack(HEX_UNPACK).first
|
65
|
+
end
|
22
66
|
|
23
67
|
# raw ore in, blocks out
|
24
68
|
def self.block(ore, size = BLOCK)
|
data/miner_mover.gemspec
CHANGED
@@ -18,13 +18,16 @@ EOF
|
|
18
18
|
s.files += Dir['test/**/*.rb']
|
19
19
|
s.files += Dir['demo/**/*.rb']
|
20
20
|
|
21
|
-
s.add_dependency "compsci", "~> 0.3"
|
22
21
|
s.add_dependency "dotcfg", "~> 1.0"
|
23
|
-
s.add_dependency "fiber_scheduler", "~> 0.13"
|
24
22
|
|
25
|
-
s.
|
26
|
-
s.
|
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
|
+
|
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"
|
28
31
|
s.add_development_dependency "flog", "~> 0"
|
29
32
|
s.add_development_dependency "flay", "~> 0"
|
30
33
|
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.
|
4
|
+
version: 0.1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rick Hull
|
@@ -10,20 +10,6 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 1980-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: compsci
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.3'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0.3'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: dotcfg
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,33 +25,19 @@ dependencies:
|
|
39
25
|
- !ruby/object:Gem::Version
|
40
26
|
version: '1.0'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0.13'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0.13'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: buildar
|
28
|
+
name: rake
|
57
29
|
requirement: !ruby/object:Gem::Requirement
|
58
30
|
requirements:
|
59
31
|
- - "~>"
|
60
32
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
33
|
+
version: '13.0'
|
62
34
|
type: :development
|
63
35
|
prerelease: false
|
64
36
|
version_requirements: !ruby/object:Gem::Requirement
|
65
37
|
requirements:
|
66
38
|
- - "~>"
|
67
39
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
40
|
+
version: '13.0'
|
69
41
|
- !ruby/object:Gem::Dependency
|
70
42
|
name: minitest
|
71
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,19 +53,19 @@ dependencies:
|
|
81
53
|
- !ruby/object:Gem::Version
|
82
54
|
version: '5.0'
|
83
55
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
56
|
+
name: buildar
|
85
57
|
requirement: !ruby/object:Gem::Requirement
|
86
58
|
requirements:
|
87
59
|
- - "~>"
|
88
60
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
61
|
+
version: '3.0'
|
90
62
|
type: :development
|
91
63
|
prerelease: false
|
92
64
|
version_requirements: !ruby/object:Gem::Requirement
|
93
65
|
requirements:
|
94
66
|
- - "~>"
|
95
67
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
68
|
+
version: '3.0'
|
97
69
|
- !ruby/object:Gem::Dependency
|
98
70
|
name: flog
|
99
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -139,13 +111,15 @@ files:
|
|
139
111
|
- demo/config.rb
|
140
112
|
- demo/fiber.rb
|
141
113
|
- demo/fiber_scheduler.rb
|
142
|
-
- demo/
|
114
|
+
- demo/process_pipe.rb
|
115
|
+
- demo/process_socket.rb
|
143
116
|
- demo/ractor.rb
|
144
117
|
- demo/serial.rb
|
145
118
|
- demo/thread.rb
|
146
119
|
- lib/miner_mover.rb
|
147
120
|
- lib/miner_mover/config.rb
|
148
121
|
- lib/miner_mover/run.rb
|
122
|
+
- lib/miner_mover/timer.rb
|
149
123
|
- lib/miner_mover/worker.rb
|
150
124
|
- miner_mover.gemspec
|
151
125
|
- test/miner_mover.rb
|
@@ -167,7 +141,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
141
|
- - ">="
|
168
142
|
- !ruby/object:Gem::Version
|
169
143
|
version: '0'
|
170
|
-
requirements:
|
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
|
171
149
|
rubygems_version: 3.3.20
|
172
150
|
signing_key:
|
173
151
|
specification_version: 4
|