Merge branch 'webpython-hybrid' of ssh://github.com/openHPI/codeocean into webpython-hybrid

This commit is contained in:
Janusch Jacoby
2015-09-16 18:37:59 +02:00
3 changed files with 49 additions and 24 deletions

1
.gitignore vendored
View File

@ -13,3 +13,4 @@
/tmp
/vagrant/
*.sublime-*
/.idea

View File

@ -93,20 +93,40 @@ class SubmissionsController < ApplicationController
Thread.new { EventMachine.run } unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive?
result = @docker_client.execute_run_command(@submission, params[:filename])
socket = result[:socket]
socket.on :message do |event|
Rails.logger.info("Docker sending: " + event.data)
handle_message(event.data, tubesock)
end
socket.on :close do |event|
if result[:status] == :container_depleted
tubesock.send_data JSON.dump({'cmd' => 'container_depleted'})
kill_socket(tubesock)
end
tubesock.onmessage do |data|
Rails.logger.info("Client sending: " + data)
socket.send data
if result[:status] == :container_running
socket = result[:socket]
socket.on :message do |event|
Rails.logger.info("Docker sending: " + event.data)
handle_message(event.data, tubesock)
end
socket.on :close do |event|
kill_socket(tubesock)
end
tubesock.onmessage do |data|
Rails.logger.info("Client sending: " + data)
# Check wether the client send a JSON command and kill container
# if the command is 'exit', send it to docker otherwise.
begin
parsed = JSON.parse(data)
if parsed['cmd'] == 'exit'
Rails.logger.info("Client killed container.")
@docker_client.kill_container(result[:container])
else
socket.send data
end
rescue JSON::ParserError
socket.send data
end
end
end
end
end
@ -134,6 +154,7 @@ class SubmissionsController < ApplicationController
parsed = JSON.parse(message)
socket.send_data message
rescue JSON::ParserError => e
# Check wether the message contains multiple lines, if true try to parse each line
if ((recursive == true) && (message.include? "\n"))
for part in message.split("\n")
self.parse_message(part,output_stream,socket,false)

View File

@ -155,7 +155,7 @@ class DockerClient
@socket ||= create_socket(@container)
# Newline required to flush
@socket.send command + "\n"
{status: :container_running, socket: @socket}
{status: :container_running, socket: @socket, container: @container}
else
{status: :container_depleted}
end
@ -170,22 +170,25 @@ class DockerClient
timeout = @execution_environment.permitted_execution_time.to_i # seconds
sleep(timeout)
Rails.logger.info("Killing container after timeout of " + timeout.to_s + " seconds.")
# if we use pooling and recylce the containers, put it back. otherwise, destroy it.
# (DockerContainerPool.config[:active] && RECYCLE_CONTAINERS) ? self.class.return_container(container, @execution_environment) : self.class.destroy_container(container)
kill_container(container)
end
end
# todo won't this always create a new container?
# remove container from pool, then destroy it
(DockerContainerPool.config[:active]) ? DockerContainerPool.remove_from_all_containers(container, @execution_environment) :
def kill_container(container)
# destroy container
self.class.destroy_container(container)
# todo won't this always create a new container?
# It does, because it's impossible to determine wether a programm is still running or not while using ws to run.
# remove container from pool, then destroy it
(DockerContainerPool.config[:active]) ? DockerContainerPool.remove_from_all_containers(container, @execution_environment) :
# if we recylce containers, we start a fresh one
if(DockerContainerPool.config[:active] && RECYCLE_CONTAINERS)
# create new container and add it to @all_containers and @containers.
container = self.class.create_container(@execution_environment)
DockerContainerPool.add_to_all_containers(container, @execution_environment)
end
#destroy container
self.class.destroy_container(container)
# if we recylce containers, we start a fresh one
if(DockerContainerPool.config[:active] && RECYCLE_CONTAINERS)
# create new container and add it to @all_containers and @containers.
container = self.class.create_container(@execution_environment)
DockerContainerPool.add_to_all_containers(container, @execution_environment)
end
end