Class: OpenC3::OperatorProcess

Inherits:
Object
  • Object
show all
Defined in:
lib/openc3/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: '/openc3/lib/openc3/microservices', temp_dir: nil, env: {}, scope:, container: nil, config: nil) ⇒ OperatorProcess

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



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/openc3/operators/operator.rb', line 92

def initialize(process_definition, work_dir: '/openc3/lib/openc3/microservices', temp_dir: nil, env: {}, scope:, container: nil, config: nil)
  @process = nil
  @process_definition = process_definition
  @work_dir = work_dir
  @temp_dir = temp_dir
  @new_temp_dir = temp_dir
  @env = env
  @scope = scope
  # @config only used in start to help print a better Logger message
  @config = config
end

Instance Attribute Details

#envObject

Returns the value of attribute env.



82
83
84
# File 'lib/openc3/operators/operator.rb', line 82

def env
  @env
end

#new_temp_dirObject

Returns the value of attribute new_temp_dir.



83
84
85
# File 'lib/openc3/operators/operator.rb', line 83

def new_temp_dir
  @new_temp_dir
end

#process_definitionObject

Returns the value of attribute process_definition.



80
81
82
# File 'lib/openc3/operators/operator.rb', line 80

def process_definition
  @process_definition
end

#scopeObject (readonly)

Returns the value of attribute scope.



85
86
87
# File 'lib/openc3/operators/operator.rb', line 85

def scope
  @scope
end

#temp_dirObject (readonly)

Returns the value of attribute temp_dir.



84
85
86
# File 'lib/openc3/operators/operator.rb', line 84

def temp_dir
  @temp_dir
end

#work_dirObject

Returns the value of attribute work_dir.



81
82
83
# File 'lib/openc3/operators/operator.rb', line 81

def work_dir
  @work_dir
end

Class Method Details

.setupObject



87
88
89
# File 'lib/openc3/operators/operator.rb', line 87

def self.setup
  # Perform any setup steps necessary
end

Instance Method Details

#alive?Boolean

Returns:

  • (Boolean)


144
145
146
147
148
149
150
# File 'lib/openc3/operators/operator.rb', line 144

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

#cmd_lineObject



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/openc3/operators/operator.rb', line 104

def cmd_line
  # In ProcessManager processes, the process_definition is the actual thing run
  # e.g. OpenC3::ProcessManager.instance.spawn(["ruby", "/openc3/bin/openc3cli", "load", ...])
  # However, if the MicroserviceOperator is spawning the proceses it sets
  # process_definition = ["ruby", "plugin_microservice.rb"]
  # which then calls exec(*@config["cmd"]) to actually run
  # So check if the @config['cmd'] is defined to give the user more info in the log
  cmd_line_text = @process_definition.join(' ')
  if @config && @config['cmd']
    cmd_line_text = @config['cmd'].join(' ')
  end
  return cmd_line_text
end

#exit_codeObject



152
153
154
155
156
157
158
# File 'lib/openc3/operators/operator.rb', line 152

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

#extract_outputObject

This is method is used in here and in ProcessManager



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/openc3/operators/operator.rb', line 204

def extract_output
  output = ''
  if @process
    stdout = @process.io.stdout.finalize
    stderr = @process.io.stderr.finalize

    # Always include the Stdout header for consistency and to show the option
    output << "Stdout:\n"
    output << stdout

    # Always include the nStderr header for consistency and to show the option
    output << "\nStderr:\n"
    output << stderr
  end
  output
end

#hard_stopObject



167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/openc3/operators/operator.rb', line 167

def hard_stop
  if @process and !@process.exited?
    # Redis may be down at this point so just catch any Logger errors
    begin
      Logger.info("Hard shutting down process: #{cmd_line()}", scope: @scope)
    rescue Exception
    end
    @process.stop
  end
  FileUtils.remove_entry(@temp_dir) if @temp_dir and File.exist?(@temp_dir)
  @process = nil
end

#output_incrementObject



188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/openc3/operators/operator.rb', line 188

def output_increment
  if @process
    stdout = @process.io.stdout.extract
    if stdout.length > 0
      STDOUT.puts "STDOUT #{stdout.length} bytes from #{cmd_line()}:"
      STDOUT.puts stdout
    end
    stderr = @process.io.stderr.extract
    if stderr.length > 0
      STDERR.puts "STDERR #{stderr.length} bytes from #{cmd_line()}:"
      STDERR.puts stderr
    end
  end
end

#soft_stopObject



160
161
162
163
164
165
# File 'lib/openc3/operators/operator.rb', line 160

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

#startObject



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/openc3/operators/operator.rb', line 118

def start
  @temp_dir = @new_temp_dir
  @new_temp_dir = nil

  Logger.info("Starting: #{cmd_line()}", 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['OPENC3_SCOPE'] = @scope
  @process.io.stdout = OperatorProcessIO.new('microservice-stdout')
  @process.io.stderr = OperatorProcessIO.new('microservice-stderr')
  @process.start
end

#stderrObject



184
185
186
# File 'lib/openc3/operators/operator.rb', line 184

def stderr
  @process.io.stderr
end

#stdoutObject



180
181
182
# File 'lib/openc3/operators/operator.rb', line 180

def stdout
  @process.io.stdout
end