jobs: migrate saved searches to ActiveJob.

* Fix tests to run the searches for real instead of mocking everything out.

* Fix SavedSearch.populate to only use the read only database in
  production because in breaks things in tests. Specifically:
  the posts get created in one db connection but searched for in
  another, but the second transaction doesn't see the uncommitted posts
  in the first transaction, so the search doesn't work.
This commit is contained in:
evazion
2019-08-16 20:49:35 -05:00
parent a68db501c2
commit 2bbdc5d143
3 changed files with 55 additions and 40 deletions

View File

@@ -0,0 +1,7 @@
class PopulateSavedSearchJob < ApplicationJob
queue_as :default
def perform(query)
SavedSearch.populate(query)
end
end

View File

@@ -32,7 +32,7 @@ class SavedSearch < ApplicationRecord
post_ids.merge(sub_ids) post_ids.merge(sub_ids)
update_count += 1 update_count += 1
else else
SavedSearch.delay(queue: "default").populate(query) PopulateSavedSearchJob.perform_later(query)
end end
end end
post_ids.to_a.sort.last(QUERY_LIMIT) post_ids.to_a.sort.last(QUERY_LIMIT)
@@ -97,7 +97,7 @@ class SavedSearch < ApplicationRecord
CurrentUser.as_system do CurrentUser.as_system do
redis_key = "search:#{query}" redis_key = "search:#{query}"
return if redis.exists(redis_key) return if redis.exists(redis_key)
post_ids = Post.tag_match(query, read_only: true).limit(QUERY_LIMIT).pluck(:id) post_ids = Post.tag_match(query, read_only: Rails.env.production?).limit(QUERY_LIMIT).pluck(:id)
redis.sadd(redis_key, post_ids) redis.sadd(redis_key, post_ids)
redis.expire(redis_key, REDIS_EXPIRY) redis.expire(redis_key, REDIS_EXPIRY)
end end

View File

@@ -60,56 +60,64 @@ class SavedSearchTest < ActiveSupport::TestCase
context ".post_ids_for" do context ".post_ids_for" do
context "with a label" do context "with a label" do
setup do setup do
SavedSearch.expects(:queries_for).with(1, label: "blah").returns(%w(a b c)) create(:saved_search, query: "a", labels: ["blah"], user: @user)
create(:saved_search, query: "b", labels: ["blah"], user: @user)
create(:saved_search, query: "c", labels: ["blah"], user: @user)
create(:post, tag_string: "a")
create(:post, tag_string: "b")
create(:post, tag_string: "c")
end end
context "without a primed cache" do context "without a primed cache" do
should "delay processing three times" do should "return nothing" do
SavedSearch.expects(:populate).times(3) post_ids = SavedSearch.post_ids_for(@user.id, label: "blah")
post_ids = SavedSearch.post_ids_for(1, label: "blah")
assert_equal([], post_ids)
end
end
context "with a primed cached" do
setup do
@mock_redis.sadd("search:a", 1)
@mock_redis.sadd("search:b", 2)
@mock_redis.sadd("search:c", 3)
end
should "fetch the post ids" do
SavedSearch.expects(:delay).never
post_ids = SavedSearch.post_ids_for(1, label: "blah")
assert_equal([1,2,3], post_ids)
end
end
end
context "without a label" do
setup do
SavedSearch.expects(:queries_for).with(1, label: nil).returns(%w(a b c))
end
context "without a primed cache" do
should "delay processing three times" do
SavedSearch.expects(:populate).times(3)
post_ids = SavedSearch.post_ids_for(1)
assert_equal([], post_ids) assert_equal([], post_ids)
end end
end end
context "with a primed cache" do context "with a primed cache" do
setup do setup do
@mock_redis.sadd("search:a", 1) perform_enqueued_jobs do
@mock_redis.sadd("search:b", 2) SavedSearch.post_ids_for(@user.id, label: "blah")
@mock_redis.sadd("search:c", 3) end
end end
should "fetch the post ids" do should "fetch the post ids" do
SavedSearch.expects(:delay).never post_ids = SavedSearch.post_ids_for(@user.id, label: "blah")
post_ids = SavedSearch.post_ids_for(1) assert_equal(Post.pluck(:id).sort, post_ids.sort)
assert_equal([1,2,3], post_ids) end
end
end
context "without a label" do
setup do
create(:saved_search, query: "a", user: @user)
create(:saved_search, query: "b", user: @user)
create(:saved_search, query: "c", user: @user)
create(:post, tag_string: "a")
create(:post, tag_string: "b")
create(:post, tag_string: "c")
end
context "without a primed cache" do
should "return nothing" do
post_ids = SavedSearch.post_ids_for(@user.id)
assert_equal([], post_ids)
end
end
context "with a primed cache" do
setup do
perform_enqueued_jobs do
SavedSearch.post_ids_for(@user.id)
end
end
should "fetch the post ids" do
post_ids = SavedSearch.post_ids_for(@user.id)
assert_equal(Post.pluck(:id).sort, post_ids.sort)
end end
end end
end end