Merge branch 'master' into statistics
This commit is contained in:
8
Gemfile
8
Gemfile
@ -5,8 +5,8 @@ gem 'bcrypt', '~> 3.1.7'
|
||||
gem 'bootstrap-will_paginate'
|
||||
gem 'carrierwave'
|
||||
gem 'coffee-rails', '~> 4.0.0'
|
||||
gem 'concurrent-ruby'
|
||||
gem 'concurrent-ruby-ext', platform: :ruby
|
||||
gem 'concurrent-ruby', '~> 1.0.0'
|
||||
gem 'concurrent-ruby-ext', '~> 1.0.0', platform: :ruby
|
||||
gem 'docker-api','~> 1.21.1', require: 'docker'
|
||||
gem 'factory_girl_rails', '~> 4.0'
|
||||
gem 'forgery'
|
||||
@ -19,9 +19,9 @@ gem 'kramdown'
|
||||
gem 'newrelic_rpm'
|
||||
gem 'pg', platform: :ruby
|
||||
gem 'pry'
|
||||
gem 'puma'
|
||||
gem 'puma', '~> 2.15.3'
|
||||
gem 'pundit'
|
||||
gem 'rails', '~> 4.1.2'
|
||||
gem 'rails', '~> 4.1.13'
|
||||
gem 'rails-i18n', '~> 4.0.0'
|
||||
gem 'ransack'
|
||||
gem 'rubytree'
|
||||
|
90
Gemfile.lock
90
Gemfile.lock
@ -2,32 +2,32 @@ GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
ZenTest (4.11.0)
|
||||
actionmailer (4.1.10)
|
||||
actionpack (= 4.1.10)
|
||||
actionview (= 4.1.10)
|
||||
actionmailer (4.1.14)
|
||||
actionpack (= 4.1.14)
|
||||
actionview (= 4.1.14)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
actionpack (4.1.10)
|
||||
actionview (= 4.1.10)
|
||||
activesupport (= 4.1.10)
|
||||
actionpack (4.1.14)
|
||||
actionview (= 4.1.14)
|
||||
activesupport (= 4.1.14)
|
||||
rack (~> 1.5.2)
|
||||
rack-test (~> 0.6.2)
|
||||
actionview (4.1.10)
|
||||
activesupport (= 4.1.10)
|
||||
actionview (4.1.14)
|
||||
activesupport (= 4.1.14)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
activemodel (4.1.10)
|
||||
activesupport (= 4.1.10)
|
||||
activemodel (4.1.14)
|
||||
activesupport (= 4.1.14)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.1.10)
|
||||
activemodel (= 4.1.10)
|
||||
activesupport (= 4.1.10)
|
||||
activerecord (4.1.14)
|
||||
activemodel (= 4.1.14)
|
||||
activesupport (= 4.1.14)
|
||||
arel (~> 5.0.0)
|
||||
activerecord-jdbc-adapter (1.3.15)
|
||||
activerecord (>= 2.2)
|
||||
activerecord-jdbcpostgresql-adapter (1.3.15)
|
||||
activerecord-jdbc-adapter (~> 1.3.15)
|
||||
jdbc-postgres (>= 9.1)
|
||||
activesupport (4.1.10)
|
||||
activesupport (4.1.14)
|
||||
i18n (~> 0.6, >= 0.6.9)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
minitest (~> 5.1)
|
||||
@ -95,11 +95,10 @@ GEM
|
||||
execjs
|
||||
coffee-script-source (1.9.1)
|
||||
colorize (0.7.7)
|
||||
concurrent-ruby (0.8.0)
|
||||
ref (~> 1.0, >= 1.0.5)
|
||||
concurrent-ruby (0.8.0-java)
|
||||
concurrent-ruby-ext (0.8.0)
|
||||
concurrent-ruby (~> 0.8.0)
|
||||
concurrent-ruby (1.0.0)
|
||||
concurrent-ruby (1.0.0-java)
|
||||
concurrent-ruby-ext (1.0.0)
|
||||
concurrent-ruby (~> 1.0.0)
|
||||
database_cleaner (1.4.1)
|
||||
debug_inspector (0.0.2)
|
||||
diff-lcs (1.2.5)
|
||||
@ -141,17 +140,17 @@ GEM
|
||||
jquery-turbolinks (2.1.0)
|
||||
railties (>= 3.1.0)
|
||||
turbolinks
|
||||
json (1.8.2)
|
||||
json (1.8.2-java)
|
||||
json (1.8.3)
|
||||
json (1.8.3-java)
|
||||
jwt (1.4.1)
|
||||
kramdown (1.6.0)
|
||||
mail (2.6.3)
|
||||
mime-types (>= 1.16, < 3)
|
||||
method_source (0.8.2)
|
||||
mime-types (2.4.3)
|
||||
mime-types (2.99)
|
||||
mini_portile (0.6.2)
|
||||
minitest (5.5.1)
|
||||
multi_json (1.11.0)
|
||||
minitest (5.8.3)
|
||||
multi_json (1.11.2)
|
||||
multi_xml (0.5.5)
|
||||
multipart-post (2.0.0)
|
||||
net-scp (1.2.1)
|
||||
@ -185,31 +184,29 @@ GEM
|
||||
method_source (~> 0.8.1)
|
||||
slop (~> 3.4)
|
||||
spoon (~> 0.0)
|
||||
puma (2.11.1)
|
||||
rack (>= 1.1, < 2.0)
|
||||
puma (2.11.1-java)
|
||||
rack (>= 1.1, < 2.0)
|
||||
puma (2.15.3)
|
||||
puma (2.15.3-java)
|
||||
pundit (0.3.0)
|
||||
activesupport (>= 3.0.0)
|
||||
rack (1.5.2)
|
||||
rack (1.5.5)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (4.1.10)
|
||||
actionmailer (= 4.1.10)
|
||||
actionpack (= 4.1.10)
|
||||
actionview (= 4.1.10)
|
||||
activemodel (= 4.1.10)
|
||||
activerecord (= 4.1.10)
|
||||
activesupport (= 4.1.10)
|
||||
rails (4.1.14)
|
||||
actionmailer (= 4.1.14)
|
||||
actionpack (= 4.1.14)
|
||||
actionview (= 4.1.14)
|
||||
activemodel (= 4.1.14)
|
||||
activerecord (= 4.1.14)
|
||||
activesupport (= 4.1.14)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.1.10)
|
||||
railties (= 4.1.14)
|
||||
sprockets-rails (~> 2.0)
|
||||
rails-i18n (4.0.4)
|
||||
i18n (~> 0.6)
|
||||
railties (~> 4.0)
|
||||
railties (4.1.10)
|
||||
actionpack (= 4.1.10)
|
||||
activesupport (= 4.1.10)
|
||||
railties (4.1.14)
|
||||
actionpack (= 4.1.14)
|
||||
activesupport (= 4.1.14)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (2.0.0)
|
||||
@ -221,7 +218,6 @@ GEM
|
||||
i18n
|
||||
polyamorous (~> 1.2)
|
||||
rdoc (4.2.0)
|
||||
ref (1.0.5)
|
||||
rspec (3.1.0)
|
||||
rspec-core (~> 3.1.0)
|
||||
rspec-expectations (~> 3.1.0)
|
||||
@ -286,12 +282,12 @@ GEM
|
||||
spoon (0.0.4)
|
||||
ffi
|
||||
spring (1.3.4)
|
||||
sprockets (2.12.3)
|
||||
sprockets (2.12.4)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sprockets-rails (2.2.4)
|
||||
sprockets-rails (2.3.3)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
@ -351,8 +347,8 @@ DEPENDENCIES
|
||||
carrierwave
|
||||
codeclimate-test-reporter
|
||||
coffee-rails (~> 4.0.0)
|
||||
concurrent-ruby
|
||||
concurrent-ruby-ext
|
||||
concurrent-ruby (~> 1.0.0)
|
||||
concurrent-ruby-ext (~> 1.0.0)
|
||||
database_cleaner
|
||||
docker-api (~> 1.21.1)
|
||||
factory_girl_rails (~> 4.0)
|
||||
@ -368,9 +364,9 @@ DEPENDENCIES
|
||||
nyan-cat-formatter
|
||||
pg
|
||||
pry
|
||||
puma
|
||||
puma (~> 2.15.3)
|
||||
pundit
|
||||
rails (~> 4.1.2)
|
||||
rails (~> 4.1.13)
|
||||
rails-i18n (~> 4.0.0)
|
||||
rake
|
||||
ransack
|
||||
|
@ -100,12 +100,12 @@ $(function() {
|
||||
}
|
||||
};
|
||||
|
||||
var confirmSubmission = function(event) {
|
||||
event.preventDefault();
|
||||
if (confirm($(this).data('message-confirm'))) {
|
||||
submitCode();
|
||||
}
|
||||
};
|
||||
//var confirmSubmission = function(event) {
|
||||
// event.preventDefault();
|
||||
// if (confirm($(this).data('message-confirm'))) {
|
||||
// submitCode();
|
||||
// }
|
||||
//};
|
||||
|
||||
var createSubmission = function(initiator, filter, callback) {
|
||||
showSpinner(initiator);
|
||||
@ -637,7 +637,8 @@ $(function() {
|
||||
|
||||
var initializeWorkflowButtons = function() {
|
||||
$('#start').on('click', showWorkspaceTab);
|
||||
$('#submit').on('click', confirmSubmission);
|
||||
//$('#submit').on('click', confirmSubmission);
|
||||
$('#submit').on('click', submitCode);
|
||||
};
|
||||
|
||||
var initializeWorkspaceButtons = function() {
|
||||
|
@ -33,6 +33,7 @@ function Turtle(pipe, canvas) {
|
||||
'x': xpos - dx,
|
||||
'y': ypos - dy
|
||||
}));
|
||||
pipe.send('\n');
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
- unless local_assigns[:modal]
|
||||
h1 = t('shared.help.headline')
|
||||
|
||||
h2 = t('shared.help.general_help')
|
||||
== Forgery(:lorem_ipsum).paragraphs(10, html: true)
|
||||
|
||||
- if local_assigns.has_key?(:execution_environment)
|
||||
h2 = t('shared.help.execution_environment_specific_help', execution_environment: execution_environment)
|
||||
= render_markdown(execution_environment.help)
|
||||
|
@ -76,8 +76,7 @@
|
||||
|
||||
br
|
||||
- if session[:lti_parameters].try(:has_key?, 'lis_outcome_service_url')
|
||||
p.text-center = render('editor_button', classes: 'btn-lg btn-success', data: {:'data-message-confirm' => t('exercises.editor.confirm_submit'), :'data-url' => submit_exercise_path(@exercise)}, icon: 'fa fa-send', id: 'submit', label: t('exercises.editor.submit'))
|
||||
|
||||
p.text-center = render('editor_button', classes: 'btn-lg btn-success', data: {:'data-url' => submit_exercise_path(@exercise)}, icon: 'fa fa-send', id: 'submit', label: t('exercises.editor.submit'))
|
||||
- if qa_url
|
||||
#questions-column
|
||||
#questions-holder data-url="#{qa_url}/qa/index/#{@exercise.id}/#{@user_id}"
|
||||
|
@ -33,6 +33,8 @@ module CodeOcean
|
||||
case (RUBY_ENGINE)
|
||||
when 'ruby'
|
||||
# ...
|
||||
#this is enabled in prod for testing
|
||||
config.middleware.use ActiveRecord::ConnectionAdapters::ConnectionManagement
|
||||
when 'jruby'
|
||||
# plattform specific
|
||||
java.lang.Class.for_name('javax.crypto.JceSecurity').get_declared_field('isRestricted').tap{|f| f.accessible = true; f.set nil, false}
|
||||
|
@ -18,8 +18,8 @@ production:
|
||||
active: true
|
||||
refill:
|
||||
async: false
|
||||
batch_size: 32
|
||||
interval: 30
|
||||
batch_size: 8
|
||||
interval: 15
|
||||
timeout: 60
|
||||
workspace_root: <%= Rails.root.join('tmp', 'files', Rails.env) %>
|
||||
ws_host: ws://localhost:4243
|
||||
|
@ -88,6 +88,8 @@ class DockerClient
|
||||
|
||||
def self.create_container(execution_environment)
|
||||
tries ||= 0
|
||||
Rails.logger.info "docker_client: self.create_container with creation options:"
|
||||
Rails.logger.info(container_creation_options(execution_environment))
|
||||
container = Docker::Container.create(container_creation_options(execution_environment))
|
||||
local_workspace_path = generate_local_workspace_path
|
||||
# container.start always creates the passed local_workspace_path on disk. Seems like we have to live with that, therefore we can also just create the empty folder ourselves.
|
||||
@ -97,7 +99,7 @@ class DockerClient
|
||||
container.status = :created
|
||||
container
|
||||
rescue Docker::Error::NotFoundError => error
|
||||
Rails.logger.info('create_container: Got Docker::Error::NotFoundError: ' + error)
|
||||
Rails.logger.info('create_container: Got Docker::Error::NotFoundError: ' + error.to_s)
|
||||
destroy_container(container)
|
||||
#(tries += 1) <= RETRY_COUNT ? retry : raise(error)
|
||||
end
|
||||
@ -113,6 +115,8 @@ class DockerClient
|
||||
create_workspace_file(container: container, file: file)
|
||||
end
|
||||
end
|
||||
rescue Docker::Error::NotFoundError => error
|
||||
Rails.logger.info('create_workspace_files: Rescued from Docker::Error::NotFoundError: ' + error.to_s)
|
||||
end
|
||||
private :create_workspace_files
|
||||
|
||||
@ -131,6 +135,9 @@ class DockerClient
|
||||
if(container)
|
||||
container.delete(force: true, v: true)
|
||||
end
|
||||
rescue Docker::Error::NotFoundError => error
|
||||
Rails.logger.error('destroy_container: Rescued from Docker::Error::NotFoundError: ' + error.to_s)
|
||||
Rails.logger.error('No further actions are done concerning that.')
|
||||
end
|
||||
|
||||
def execute_arbitrary_command(command, &block)
|
||||
@ -297,7 +304,12 @@ class DockerClient
|
||||
|
||||
def self.return_container(container, execution_environment)
|
||||
Rails.logger.debug('returning container ' + container.to_s)
|
||||
clean_container_workspace(container)
|
||||
begin
|
||||
clean_container_workspace(container)
|
||||
rescue Docker::Error::NotFoundError => error
|
||||
Rails.logger.info('return_container: Rescued from Docker::Error::NotFoundError: ' + error.to_s)
|
||||
Rails.logger.info('Nothing is done here additionally. The container will be exchanged upon its next retrieval.')
|
||||
end
|
||||
DockerContainerPool.return_container(container, execution_environment)
|
||||
container.status = :returned
|
||||
end
|
||||
|
@ -1,6 +1,6 @@
|
||||
require 'concurrent/future'
|
||||
require 'concurrent/timer_task'
|
||||
require 'concurrent/utilities'
|
||||
|
||||
|
||||
class DockerContainerPool
|
||||
|
||||
@ -18,10 +18,19 @@ class DockerContainerPool
|
||||
@config ||= CodeOcean::Config.new(:docker).read(erb: true)[:pool]
|
||||
end
|
||||
|
||||
def self.containers
|
||||
@containers
|
||||
end
|
||||
|
||||
def self.all_containers
|
||||
@all_containers
|
||||
end
|
||||
|
||||
def self.remove_from_all_containers(container, execution_environment)
|
||||
@all_containers[execution_environment.id]-=[container]
|
||||
if(@containers[execution_environment.id].include?(container))
|
||||
@containers[execution_environment.id]-=[container]
|
||||
Rails.logger.debug('Removed container ' + container.to_s + ' from all_pool for execution environment ' + execution_environment.to_s + '. Remaining containers in all_pool ' + @all_containers[execution_environment.id].size.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
@ -29,6 +38,7 @@ class DockerContainerPool
|
||||
@all_containers[execution_environment.id]+=[container]
|
||||
if(!@containers[execution_environment.id].include?(container))
|
||||
@containers[execution_environment.id]+=[container]
|
||||
Rails.logger.debug('Added container ' + container.to_s + ' to all_pool for execution environment ' + execution_environment.to_s + '. Containers in all_pool: ' + @all_containers[execution_environment.id].size.to_s)
|
||||
else
|
||||
Rails.logger.info('failed trying to add existing container ' + container.to_s + ' to execution_environment ' + execution_environment.to_s)
|
||||
end
|
||||
@ -57,9 +67,28 @@ class DockerContainerPool
|
||||
Rails.logger.debug('get_container fetched container ' + container.to_s + ' for execution environment ' + execution_environment.to_s)
|
||||
# just access and the following if we got a container. Otherwise, the execution_environment might be just created and not fully exist yet.
|
||||
if(container)
|
||||
Rails.logger.debug('get_container remaining avail. containers: ' + @containers[execution_environment.id].size.to_s)
|
||||
Rails.logger.debug('get_container all container count: ' + @all_containers[execution_environment.id].size.to_s)
|
||||
begin
|
||||
# check whether the container is running. exited containers go to the else part.
|
||||
# Dead containers raise a NotFOundError on the container.json call. This is handled in the rescue block.
|
||||
if(container.json['State']['Running'])
|
||||
Rails.logger.debug('get_container remaining avail. containers: ' + @containers[execution_environment.id].size.to_s)
|
||||
Rails.logger.debug('get_container all container count: ' + @all_containers[execution_environment.id].size.to_s)
|
||||
else
|
||||
Rails.logger.error('docker_container_pool.get_container retrieved a container not running. Container will be removed from list: ' + container.to_s)
|
||||
remove_from_all_containers(container, execution_environment)
|
||||
Rails.logger.error('Creating a new container and returning that.')
|
||||
container = create_container(execution_environment)
|
||||
DockerContainerPool.add_to_all_containers(container, execution_environment)
|
||||
end
|
||||
rescue Docker::Error::NotFoundError => error
|
||||
Rails.logger.error('docker_container_pool.get_container rescued from Docker::Error::NotFoundError. Most likely, the container is not there any longer. Removing faulty entry from list: ' + container.to_s)
|
||||
remove_from_all_containers(container, execution_environment)
|
||||
Rails.logger.error('Creating a new container and returning that.')
|
||||
container = create_container(execution_environment)
|
||||
DockerContainerPool.add_to_all_containers(container, execution_environment)
|
||||
end
|
||||
end
|
||||
# returning nil is no problem. then the pool is just depleted.
|
||||
container
|
||||
else
|
||||
create_container(execution_environment)
|
||||
@ -71,7 +100,7 @@ class DockerContainerPool
|
||||
end
|
||||
|
||||
def self.refill
|
||||
ExecutionEnvironment.where('pool_size > 0').each do |execution_environment|
|
||||
ExecutionEnvironment.where('pool_size > 0').order(pool_size: :desc).each do |execution_environment|
|
||||
if config[:refill][:async]
|
||||
Concurrent::Future.execute { refill_for_execution_environment(execution_environment) }
|
||||
else
|
||||
@ -85,18 +114,19 @@ class DockerContainerPool
|
||||
if refill_count > 0
|
||||
Rails.logger.info('Adding ' + refill_count.to_s + ' containers for execution_environment ' + execution_environment.name )
|
||||
c = refill_count.times.map { create_container(execution_environment) }
|
||||
Rails.logger.debug('Created containers: ' + c.to_s )
|
||||
Rails.logger.info('Created containers: ' + c.to_s )
|
||||
#c.each { |container| return_container(container, execution_environment) }
|
||||
@containers[execution_environment.id] += c
|
||||
@all_containers[execution_environment.id] += c
|
||||
Rails.logger.debug('@containers ' + @containers.object_id.to_s + ' has:'+ @containers[execution_environment.id].to_s)
|
||||
Rails.logger.debug('@all_containers ' + @containers.object_id.to_s + ' has:'+ @all_containers[execution_environment.id].to_s)
|
||||
Rails.logger.debug('@containers for ' + execution_environment.name.to_s + ' (' + @containers.object_id.to_s + ') has the following content: '+ @containers[execution_environment.id].to_s)
|
||||
Rails.logger.debug('@all_containers for ' + execution_environment.name.to_s + ' (' + @all_containers.object_id.to_s + ') has the following content: ' + @all_containers[execution_environment.id].to_s)
|
||||
#refill_count.times.map { create_container(execution_environment) }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def self.start_refill_task
|
||||
@refill_task = Concurrent::TimerTask.new(execution_interval: config[:refill][:interval], run_now: false, timeout_interval: config[:refill][:timeout]) { refill }
|
||||
@refill_task = Concurrent::TimerTask.new(execution_interval: config[:refill][:interval], run_now: true, timeout_interval: config[:refill][:timeout]) { refill }
|
||||
@refill_task.execute
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user