Class: Cosmos::OperatorProcess

Inherits:
Object
  • Object
show all
Defined in:
lib/cosmos/operators/operator.rb

Direct Known Subclasses

ProcessManagerProcess

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(process_definition, work_dir: '/cosmos/lib/cosmos/microservices', temp_dir: nil, env: {}, scope:, container: nil) ⇒ OperatorProcess

container is not used, it’s just here for Enterprise



38
39
40
41
42
43
44
45
46
# File 'lib/cosmos/operators/operator.rb', line 38

def initialize(process_definition, work_dir: '/cosmos/lib/cosmos/microservices', temp_dir: nil, env: {}, scope:, container: nil) # container is not used, it's just here for Enterprise
  @process = nil
  @process_definition = process_definition
  @work_dir = work_dir
  @temp_dir = temp_dir
  @new_temp_dir = temp_dir
  @env = env
  @scope = scope
end

Instance Attribute Details

#envObject

Returns the value of attribute env.



29
30
31
# File 'lib/cosmos/operators/operator.rb', line 29

def env
  @env
end

#new_temp_dirObject

Returns the value of attribute new_temp_dir.



30
31
32
# File 'lib/cosmos/operators/operator.rb', line 30

def new_temp_dir
  @new_temp_dir
end

#process_definitionObject

Returns the value of attribute process_definition.



27
28
29
# File 'lib/cosmos/operators/operator.rb', line 27

def process_definition
  @process_definition
end

#scopeObject (readonly)

Returns the value of attribute scope.



32
33
34
# File 'lib/cosmos/operators/operator.rb', line 32

def scope
  @scope
end

#temp_dirObject (readonly)

Returns the value of attribute temp_dir.



31
32
33
# File 'lib/cosmos/operators/operator.rb', line 31

def temp_dir
  @temp_dir
end

#work_dirObject

Returns the value of attribute work_dir.



28
29
30
# File 'lib/cosmos/operators/operator.rb', line 28

def work_dir
  @work_dir
end

Class Method Details

.setupObject



34
35
36
# File 'lib/cosmos/operators/operator.rb', line 34

def self.setup
  # Perform any setup steps necessary
end

Instance Method Details

#alive?Boolean

Returns:

  • (Boolean)


72
73
74
75
76
77
78
# File 'lib/cosmos/operators/operator.rb', line 72

def alive?
  if @process
    @process.alive?
  else
    false
  end
end

#exit_codeObject



80
81
82
83
84
85
86
# File 'lib/cosmos/operators/operator.rb', line 80

def exit_code
  if @process
    @process.exit_code
  else
    nil
  end
end

#extract_output(max_length_stdout = 65536, max_length_stderr = 65536) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/cosmos/operators/operator.rb', line 112

def extract_output(max_length_stdout = 65536, max_length_stderr = 65536)
  if @process
    @process.io.stdout.rewind
    output = @process.io.stdout.read
    @process.io.stdout.close
    @process.io.stdout.unlink
    @process.io.stderr.rewind
    err_output = @process.io.stderr.read
    @process.io.stderr.close
    @process.io.stderr.unlink
    return "Stdout:\n#{output[-max_length_stdout..-1] || output}\n\nStderr:\n#{err_output[-max_length_stderr..-1] || err_output}\n"
  else
    return ""
  end
end

#hard_stopObject



95
96
97
98
99
100
101
102
# File 'lib/cosmos/operators/operator.rb', line 95

def hard_stop
  if @process and !@process.exited?
    Logger.info("Hard shutting down process: #{@process_definition.join(' ')}", scope: @scope)
    @process.stop
  end
  FileUtils.remove_entry(@temp_dir) if @temp_dir and File.exist?(@temp_dir)
  @process = nil
end

#soft_stopObject



88
89
90
91
92
93
# File 'lib/cosmos/operators/operator.rb', line 88

def soft_stop
  Thread.new do
    Logger.info("Soft shutting down process: #{@process_definition.join(' ')}", scope: @scope)
    Process.kill("SIGINT", @process.pid) if @process # Signal the process to stop
  end
end

#startObject



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/cosmos/operators/operator.rb', line 48

def start
  @temp_dir = @new_temp_dir
  @new_temp_dir = nil
  Logger.info("Starting: #{@process_definition.join(' ')}", scope: @scope)
  @process = ChildProcess.build(*@process_definition)
  # This lets the ChildProcess use the parent IO ... but it breaks unit tests
  # @process.io.inherit!
  @process.cwd = @work_dir
  # Spawned process should not be controlled by same Bundler constraints as spawning process
  ENV.each do |key, value|
    if key =~ /^BUNDLER/
      @process.environment[key] = nil
    end
  end
  @env['RUBYOPT'] = nil # Removes loading bundler setup
  @env.each do |key, value|
    @process.environment[key] = value
  end
  @process.environment['COSMOS_SCOPE'] = @scope
  @process.io.stdout = Tempfile.new("child-output")
  @process.io.stderr = Tempfile.new("child-output")
  @process.start
end

#stderrObject



108
109
110
# File 'lib/cosmos/operators/operator.rb', line 108

def stderr
  @process.io.stderr
end

#stdoutObject



104
105
106
# File 'lib/cosmos/operators/operator.rb', line 104

def stdout
  @process.io.stdout
end