From d446c44d5b0512a0f6b148cb89bf5bf923c03ef9 Mon Sep 17 00:00:00 2001 From: Joel Low Date: Fri, 1 Apr 2016 09:03:37 +0800 Subject: [PATCH] If an evaluation was allocated at the last attempt, immediately request for more. This is so that when there is a queue of evaluations, the one minute cool down time is not used. --- lib/coursemology/evaluator/client.rb | 34 +++++++++++++--------- spec/coursemology/evaluator/client_spec.rb | 26 ++++++++++------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/lib/coursemology/evaluator/client.rb b/lib/coursemology/evaluator/client.rb index fef2dcb..3cfae63 100644 --- a/lib/coursemology/evaluator/client.rb +++ b/lib/coursemology/evaluator/client.rb @@ -17,30 +17,36 @@ def run Signal.trap('SIGTERM', method(:on_sig_term)) loop do - allocate_evaluations - break if @terminate + evaluations = allocate_evaluations + + if evaluations && !evaluations.empty? + on_allocate(evaluations) + else + # :nocov: + # This sleep might not be triggered in the specs, because interruptions to the thread is + # nondeterministically run by the OS scheduler. + sleep(1.minute) + # :nocov: + end - # :nocov: - # This sleep might not be triggered in the specs, because interruptions to the thread is - # nondeterministically run by the OS scheduler. - sleep(1.minute) - # :nocov: + break if @terminate end end private # Requests evaluations from the server. + # + # @return [Array] The evaluations + # retrieved from the server. def allocate_evaluations - evaluations = - ActiveSupport::Notifications.instrument('allocate.client.evaluator.coursemology') do - languages = Coursemology::Polyglot::Language.concrete_languages.map(&:display_name) - Coursemology::Evaluator::Models::ProgrammingEvaluation.allocate(language: languages) - end - - on_allocate(evaluations) + ActiveSupport::Notifications.instrument('allocate.client.evaluator.coursemology') do + languages = Coursemology::Polyglot::Language.concrete_languages.map(&:display_name) + Coursemology::Evaluator::Models::ProgrammingEvaluation.allocate(language: languages) + end rescue Flexirest::HTTPUnauthorisedClientException => e ActiveSupport::Notifications.publish('allocate_fail.client.evaluator.coursemology', e: e) + nil end # The callback for handling an array of allocated evaluations. diff --git a/spec/coursemology/evaluator/client_spec.rb b/spec/coursemology/evaluator/client_spec.rb index 6ca8895..895eb61 100644 --- a/spec/coursemology/evaluator/client_spec.rb +++ b/spec/coursemology/evaluator/client_spec.rb @@ -18,6 +18,8 @@ end describe '#run' do + let(:dummy_evaluation) { build_stubbed(:programming_evaluation) } + it 'loops until @terminate is set' do expect(subject).to receive(:allocate_evaluations).at_least(:once) allow(subject).to receive(:sleep) { sleep(0.1.seconds) } @@ -25,22 +27,24 @@ Thread.new { subject.instance_variable_set(:@terminate, true) } subject.run end + + it 'calls #on_allocate with the evaluation' do + called = false + expect(subject).to receive(:allocate_evaluations) do + called ? [] : [dummy_evaluation] + end.at_least(:once) + + expect(subject).to receive(:on_allocate).with([dummy_evaluation]).at_least(:once) + Thread.new { subject.send(:on_sig_term) } + subject.run + end end describe '#allocate_evaluations' do context 'when an evaluation is provided' do - let(:dummy_evaluation) { build_stubbed(:programming_evaluation) } - before do - expect(Coursemology::Evaluator::Models::ProgrammingEvaluation).to \ - receive(:allocate).and_return([dummy_evaluation]) - end - - it 'calls #on_evaluation with the evaluation' do - expect(subject).to receive(:on_evaluation).with(dummy_evaluation) - subject.send(:allocate_evaluations) - end - it 'instruments the allocation request' do + expect(Coursemology::Evaluator::Models::ProgrammingEvaluation).to \ + receive(:allocate).and_return(nil) expect { subject.send(:allocate_evaluations) }.to \ instrument_notification('allocate.client.evaluator.coursemology') end