diff --git a/lib/postgresql_selection.rb b/lib/postgresql_selection.rb index 261946a05..57d99d25b 100644 --- a/lib/postgresql_selection.rb +++ b/lib/postgresql_selection.rb @@ -1,6 +1,8 @@ class PostgresqlSelection attr_reader :workflow, :user, :opts + MAX_RANDOM_SAMPLE_ATTEMPTS = 100 + def initialize(workflow, user=nil) @workflow, @user = workflow, user end @@ -65,8 +67,11 @@ def select_results_in_order def construct_random_sample_to_limit results = [] + attempt = 0 until results.length >= limit do results = results | sample.limit(limit).pluck(:id) + attempt += 1 + break if attempt >= MAX_RANDOM_SAMPLE_ATTEMPTS end results end diff --git a/spec/lib/postgresql_selection_spec.rb b/spec/lib/postgresql_selection_spec.rb index df96b7a61..b7fec1b5f 100644 --- a/spec/lib/postgresql_selection_spec.rb +++ b/spec/lib/postgresql_selection_spec.rb @@ -27,7 +27,6 @@ def update_sms_priorities sms_scope.count - _seen_count end - context "when a user has only seen a few subjects" do let(:seen_count) { 5 } let!(:uss) do @@ -87,6 +86,14 @@ def update_sms_priorities subject { PostgresqlSelection.new(workflow, user) } it_behaves_like "select for incomplete_project" + + it "should give up trying to construct a random list after set number of attempts" do + unreachable_limit = SetMemberSubject.count + 1 + allow_any_instance_of(PostgresqlSelection).to receive(:available_count).and_return(unreachable_limit + 1) + allow_any_instance_of(PostgresqlSelection).to receive(:limit).and_return(unreachable_limit) + results = subject.select + expect(results).to eq(results) + end end context "grouped selection" do