miner_mover 0.0.0.4 → 0.1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|