Class: TWPipeline::Resources

Inherits:
Data
  • Object
show all
Defined in:
lib/twpipeline/resources.rb,
sig/twpipeline.rbs

Constant Summary collapse

UNITS =

Returns:

  • (::Hash[::String, ::Integer])
{"K" => 1024, "M" => 1024 ** 2, "G" => 1024 ** 3, "T" => 1024 ** 4}.freeze
DEFAULT_SHARE =

Returns:

  • (::Float)
0.5

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#coresObject (readonly)

Returns the value of attribute cores

Returns:

  • (Object)

    the current value of cores



6
7
8
# File 'lib/twpipeline/resources.rb', line 6

def cores
  @cores
end

#memory_bytesObject (readonly)

Returns the value of attribute memory_bytes

Returns:

  • (Object)

    the current value of memory_bytes



6
7
8
# File 'lib/twpipeline/resources.rb', line 6

def memory_bytes
  @memory_bytes
end

Class Method Details

.ask(io: $stderr, input: $stdin) ⇒ Resources

Parameters:

  • io: (::IO) (defaults to: $stderr)
  • input: (::IO) (defaults to: $stdin)

Returns:



35
36
37
38
39
40
41
42
43
# File 'lib/twpipeline/resources.rb', line 35

def ask(io: $stderr, input: $stdin)
  suggested = detect
  io.print("cores [#{suggested.cores}]: ")
  cores = input.gets.to_s.strip
  io.print("usable memory [#{suggested.memory}]: ")
  memory = input.gets.to_s.strip

  detect(cores: cores.empty? ? nil : cores, memory: memory.empty? ? nil : memory)
end

.detect(cores: nil, memory: nil) ⇒ Resources

Parameters:

  • cores: (Object) (defaults to: nil)
  • memory: (Object) (defaults to: nil)

Returns:



28
29
30
31
32
33
# File 'lib/twpipeline/resources.rb', line 28

def detect(cores: nil, memory: nil)
  new(
    cores: (cores || ENV["TWP_CORES"] || Etc.nprocessors).to_i.clamp(1, 1024),
    memory_bytes: parse(memory || ENV["TWP_MEMORY"]) || (total_memory * DEFAULT_SHARE).to_i
  )
end

.parse(value) ⇒ ::Integer?

Parameters:

  • value (Object)

Returns:

  • (::Integer, nil)

Raises:



45
46
47
48
49
50
51
52
53
# File 'lib/twpipeline/resources.rb', line 45

def parse(value)
  return nil if value.nil? || value.to_s.strip.empty?
  return value if value.is_a?(Integer)

  match = value.to_s.strip.upcase.match(/\A(\d+(?:\.\d+)?)\s*([KMGT])?B?\z/)
  raise Error, "cannot parse memory size: #{value}" if match.nil?

  (match[1].to_f * UNITS.fetch(match[2], 1)).to_i
end

.total_memory::Integer

Returns:

  • (::Integer)


55
56
57
58
59
60
61
# File 'lib/twpipeline/resources.rb', line 55

def total_memory
  @total_memory ||= if RUBY_PLATFORM.include?("darwin")
    `sysctl -n hw.memsize`.to_i
  else
    File.read("/proc/meminfo")[/MemTotal:\s+(\d+) kB/, 1].to_i * 1024
  end
end

Instance Method Details

#memory::String

Returns:

  • (::String)


10
# File 'lib/twpipeline/resources.rb', line 10

def memory = format_bytes(memory_bytes)

#memory_per_worker_bytes::Integer

Returns:

  • (::Integer)


14
# File 'lib/twpipeline/resources.rb', line 14

def memory_per_worker_bytes = memory_bytes / [cores, 1].max

#sort_buffer::String

Returns:

  • (::String)


12
# File 'lib/twpipeline/resources.rb', line 12

def sort_buffer = format_bytes((memory_bytes * 0.8).to_i)

#to_h::Hash[::Symbol, untyped]

Returns:

  • (::Hash[::Symbol, untyped])


16
# File 'lib/twpipeline/resources.rb', line 16

def to_h = {cores: cores, memory_bytes: memory_bytes, memory: memory}

#to_s::String

Returns:

  • (::String)


18
# File 'lib/twpipeline/resources.rb', line 18

def to_s = "#{cores} cores, #{memory} usable"