Split WebSocket event in multiple lines before processing
This commit is contained in:
@ -78,8 +78,13 @@ class Runner::Connection
|
|||||||
|
|
||||||
def on_message(raw_event)
|
def on_message(raw_event)
|
||||||
Rails.logger.debug { "#{Time.zone.now.getutc}: Receiving from #{@socket.url}: #{raw_event.data.inspect}" }
|
Rails.logger.debug { "#{Time.zone.now.getutc}: Receiving from #{@socket.url}: #{raw_event.data.inspect}" }
|
||||||
event = decode(raw_event)
|
# The WebSocket connection might group multiple lines. For further processing, we require all lines
|
||||||
return unless BACKEND_OUTPUT_SCHEMA.valid?(event)
|
# to be processed separately. Therefore, we split the lines by each newline character not part of an enclosed
|
||||||
|
# substring either in single or double quotes (e.g., within a JSON)
|
||||||
|
# Inspired by https://stackoverflow.com/questions/13040585/split-string-by-spaces-properly-accounting-for-quotes-and-backslashes-ruby
|
||||||
|
raw_event.data.scan(/(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|[^"\n])+/).each do |event_data|
|
||||||
|
event = decode(event_data)
|
||||||
|
next unless BACKEND_OUTPUT_SCHEMA.valid?(event)
|
||||||
|
|
||||||
event = event.deep_symbolize_keys
|
event = event.deep_symbolize_keys
|
||||||
message_type = event[:type].to_sym
|
message_type = event[:type].to_sym
|
||||||
@ -90,6 +95,7 @@ class Runner::Connection
|
|||||||
close(:error)
|
close(:error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def on_open(_event)
|
def on_open(_event)
|
||||||
@start_callback.call
|
@start_callback.call
|
||||||
|
@ -121,9 +121,9 @@ class Runner::Strategy::DockerContainerPool < Runner::Strategy
|
|||||||
"#{data}\n"
|
"#{data}\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
def decode(raw_event)
|
def decode(event_data)
|
||||||
case raw_event.data
|
case event_data
|
||||||
when /@#{@strategy.container_id[0..11]}/
|
when /(@#{@strategy.container_id[0..11]}|#exit)/
|
||||||
# Assume correct termination for now and return exit code 0
|
# Assume correct termination for now and return exit code 0
|
||||||
# TODO: Can we use the actual exit code here?
|
# TODO: Can we use the actual exit code here?
|
||||||
@exit_code = 0
|
@exit_code = 0
|
||||||
@ -135,11 +135,11 @@ class Runner::Strategy::DockerContainerPool < Runner::Strategy
|
|||||||
when /\*\*\*\*\*\*\*\*\*\*\*\*\* Module/
|
when /\*\*\*\*\*\*\*\*\*\*\*\*\* Module/
|
||||||
# Identification of PyLint output, change stream back to stdout and return event
|
# Identification of PyLint output, change stream back to stdout and return event
|
||||||
@stream = 'stdout'
|
@stream = 'stdout'
|
||||||
{'type' => @stream, 'data' => raw_event.data}
|
{'type' => @stream, 'data' => event_data}
|
||||||
when /#{@strategy.command}/
|
when /#{@strategy.command}/
|
||||||
when /bash: cmd:canvasevent: command not found/
|
when /bash: cmd:canvasevent: command not found/
|
||||||
else
|
else
|
||||||
{'type' => @stream, 'data' => raw_event.data}
|
{'type' => @stream, 'data' => event_data}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -151,8 +151,8 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
|||||||
end
|
end
|
||||||
|
|
||||||
class Connection < Runner::Connection
|
class Connection < Runner::Connection
|
||||||
def decode(raw_event)
|
def decode(event_data)
|
||||||
JSON.parse(raw_event.data)
|
JSON.parse(event_data)
|
||||||
rescue JSON::ParserError => e
|
rescue JSON::ParserError => e
|
||||||
@error = Runner::Error::UnexpectedResponse.new("The WebSocket message from Poseidon could not be decoded to JSON: #{e.inspect}")
|
@error = Runner::Error::UnexpectedResponse.new("The WebSocket message from Poseidon could not be decoded to JSON: #{e.inspect}")
|
||||||
close(:error)
|
close(:error)
|
||||||
|
Reference in New Issue
Block a user