From 125fa18594fc6ea1f26c4f2f30c96709c8d66e36 Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Mon, 25 May 2015 01:20:53 +0200 Subject: [PATCH 1/3] Run view model fetches in threads --- config/environments/development.rb | 2 ++ config/environments/production.rb | 1 + config/environments/test.rb | 4 +++- lib/view_model.rb | 34 +++++++++++++++++++++++++----- test/unit/view_model_test.rb | 1 + 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/config/environments/development.rb b/config/environments/development.rb index 308c82e..5f8e06a 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -26,4 +26,6 @@ config.assets.debug = true config.eager_load = false + + config.active_record.raise_in_transactional_callbacks = true end diff --git a/config/environments/production.rb b/config/environments/production.rb index df78036..2339b0b 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -64,4 +64,5 @@ config.logger = Logger::Syslog.new("local0", Syslog::LOG_LOCAL5) + config.active_record.raise_in_transactional_callbacks = true end diff --git a/config/environments/test.rb b/config/environments/test.rb index e654ae3..0fde03d 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -37,7 +37,9 @@ # Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets config.assets.allow_debugging = true - config.eager_load = false + config.eager_load = true config.active_support.test_order = :random + + config.active_record.raise_in_transactional_callbacks = true end diff --git a/lib/view_model.rb b/lib/view_model.rb index ca4a503..f42ed82 100644 --- a/lib/view_model.rb +++ b/lib/view_model.rb @@ -46,23 +46,47 @@ def initialize(attrs={}) end def finalize + t = Time.now.to_f dependencies = [] + threads = [] self.class.fetch_args.each do |arg| - if !send("fetch_#{arg}") - dependencies << arg + threads << Thread.new do + ActiveRecord::Base.connection_pool.with_connection do + Rails.logger.info "view model thread #{arg} start" + t1 = Time.now.to_f + if !send("fetch_#{arg}") + dependencies << arg + end + Rails.logger.info "view model thread #{arg} finished (#{"%.1f" % ((Time.now.to_f - t1) * 1000)}ms)" + end end end + threads.each do |t| + t.join + end + threads = [] while dependencies.size > 0 d = [] dependencies.each do |arg| - if !send("fetch_#{arg}") - d << arg + threads << Thread.new do + ActiveRecord::Base.connection_pool.with_connection do + Rails.logger.info "view model thread #{arg} start" + t1 = Time.now.to_f + if !send("fetch_#{arg}") + d << arg + end + Rails.logger.info "view model thread #{arg} finished (#{"%.1f" % ((Time.now.to_f - t1) * 1000)}ms)" + end end end + threads.each do |t| + t.join + end + threads = [] dependencies = d end - Rails.logger.info "view model finalized" + Rails.logger.info "view model finalized (#{"%.1f" % ((Time.now.to_f - t) * 1000)}ms)" end end diff --git a/test/unit/view_model_test.rb b/test/unit/view_model_test.rb index 0e19aea..306abb8 100644 --- a/test/unit/view_model_test.rb +++ b/test/unit/view_model_test.rb @@ -1,6 +1,7 @@ require 'test_helper' class ViewModelTest < ActiveSupport::TestCase + self.use_transactional_fixtures = false def setup create_user From 3754d8ea33d5e7cac49ffe73a0bef0a365ffb5d8 Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Thu, 14 Apr 2016 20:47:31 +0200 Subject: [PATCH 2/3] Fix view dependencies --- app/models/views/channel_list.rb | 12 ++++-------- app/models/views/search.rb | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/app/models/views/channel_list.rb b/app/models/views/channel_list.rb index 4c9318b..9a6cd97 100644 --- a/app/models/views/channel_list.rb +++ b/app/models/views/channel_list.rb @@ -6,19 +6,15 @@ class ChannelList < ListView fetches :filter_ids, proc { Channel.filter_ids(site, query, current_user) } fetches :recent_channels, proc { Channel.recent_channels(site, current_user, page, per_page, last_update_date, filter_ids) }, [:filter_ids] fetches :channels_read, proc { - recent_channels.each do |channel| - channel.read = channel.has_posts?(current_user, channel.last_post) - end + recent_channels.each { |channel| channel.read = channel.has_posts?(current_user, channel.last_post) } nil }, [:recent_channels] fetches :highlight_query, proc { - recent_channels.each do |channel| - channel.query = query - end + recent_channels.each { |channel| channel.query = query } nil - } + }, [:recent_channels] - fetches :count, proc { recent_channels.count } + fetches :count, proc { recent_channels.count }, [:recent_channels] fetches :start_index, proc { (page - 1) * per_page } fetches :end_index, proc { (page - 1) * per_page + recent_channels.size }, [:recent_channels] fetches :last_update, proc { (recent_channels.map(&:created_at) + recent_channels.map(&:updated_at) + recent_channels.map(&:last_post_date)).map(&:utc).max.to_i }, [:recent_channels] diff --git a/app/models/views/search.rb b/app/models/views/search.rb index 807695c..5c555b7 100644 --- a/app/models/views/search.rb +++ b/app/models/views/search.rb @@ -13,7 +13,7 @@ class Search < ListView end end nil - } + }, [:results] fetches :last_update, proc { Time.now } fetches :count, proc { results[:result_count] }, [:results] From c0a313004c50154c93ef77d659e4c78432665b28 Mon Sep 17 00:00:00 2001 From: Mutwin Kraus Date: Thu, 14 Apr 2016 20:55:05 +0200 Subject: [PATCH 3/3] Debug output in failing api tests --- test/integration/api/api_channels_test.rb | 3 +++ test/integration/api/api_posts_test.rb | 1 + 2 files changed, 4 insertions(+) diff --git a/test/integration/api/api_channels_test.rb b/test/integration/api/api_channels_test.rb index 35fc3ec..24966c7 100644 --- a/test/integration/api/api_channels_test.rb +++ b/test/integration/api/api_channels_test.rb @@ -11,6 +11,7 @@ class ApiChannelsTest < ActionDispatch::IntegrationTest c = create_channel(title) get '/api/channels.json' j = json_body + puts j.inspect jc = j['channels'].first assert_equal c.id, jc['id'] assert_equal c.title, jc['title'] @@ -26,6 +27,7 @@ class ApiChannelsTest < ActionDispatch::IntegrationTest title = "Test Channel #{Time.now.to_f}" post '/api/channels.json', {channel: {title: title, body: "Testing"}} j = json_body + puts j.inspect assert_nil json_body['errors'] jc = j['channel'] assert_not_nil jc['id'] @@ -46,6 +48,7 @@ class ApiChannelsTest < ActionDispatch::IntegrationTest title2 = "FooTest Channel #{Time.now.to_f}" put "/api/channels/#{c.id}.json", {channel: {title: title2, text: "Channel text"}} j = json_body + puts j.inspect jc = j['channel'] assert_equal title2, jc['title'] assert_equal "Channel text", jc['text'] diff --git a/test/integration/api/api_posts_test.rb b/test/integration/api/api_posts_test.rb index 2f2980c..bf3fa31 100644 --- a/test/integration/api/api_posts_test.rb +++ b/test/integration/api/api_posts_test.rb @@ -46,6 +46,7 @@ class ApiPostsTest < ActionDispatch::IntegrationTest p = create_post("Post") get "/api/channels/#{c.id}/posts.json" j = json_body + puts j.inspect jc = j['channel'] assert_equal c.id, jc['id'] jp = j['posts'].last