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
         
     |