From ff73c170bdfdf53ec03d14c48d2f441c901ec1f6 Mon Sep 17 00:00:00 2001 From: Jonathan Kolyer Date: Sat, 26 Jul 2014 03:58:58 +0000 Subject: [PATCH] VRFS-1942 refactoring scheduled session emails; new admin view into batch email data queries --- .../admin/email_daily_scheduled_session.rb | 79 ++++++ ruby/lib/jam_ruby/models/email_batch.rb | 7 + .../jam_ruby/models/email_batch_periodic.rb | 1 + .../models/email_batch_scheduled_sessions.rb | 263 ++++++++++++------ 4 files changed, 265 insertions(+), 85 deletions(-) create mode 100644 admin/app/admin/email_daily_scheduled_session.rb diff --git a/admin/app/admin/email_daily_scheduled_session.rb b/admin/app/admin/email_daily_scheduled_session.rb new file mode 100644 index 000000000..2fc9f4efd --- /dev/null +++ b/admin/app/admin/email_daily_scheduled_session.rb @@ -0,0 +1,79 @@ +ActiveAdmin.register JamRuby::EmailBatchScheduledSessions, :as => 'Daily Sessions' do + + menu :label => 'Daily Sessions', :parent => 'Email' + + config.sort_order = 'updated_at DESC' + config.filters = false + config.batch_actions = false + config.clear_action_items! + + index do + column 'Created' do |bb| bb.created_at end + column 'Status' do |bb| bb.aasm_state end + column 'Sent Count' do |bb| bb.sent_count end + column 'Counters' do |bb| bb.test_emails end + column 'Started' do |bb| bb.started_at end + column 'Completed' do |bb| bb.completed_at end + end + + action_item :only => [:index] do + link_to('Daily Session Snapshot', new_admin_daily_session_path) + end + + show :title => "Daily Session Snapshot" do |obj| + h3 "Session created range: (#{obj.earliest_session_create_time}, #{obj.latest_session_create_time}); Earliest session start: #{obj.earliest_session_start_time}" + h3 "Max Latency Score: #{params[:max_score] ? params[:max_score] : Score::MAX_YELLOW_LATENCY}" + h4 "(append URL with ?max_score=NN to change max latency from default (#{Score::MAX_YELLOW_LATENCY}))" + + num, objs = obj.snapshot_scored_recipients + panel "Session & Scoring Matches (#{num})" do + table_for(objs) do + column :receiver_id do |oo| + link_to(oo.vals['receiver_id'], admin_user_path(oo.vals['receiver_id']), {:target => '_blank'}) + end + column :session_id do |oo| + link_to(oo.vals['session_id'], admin_music_session_path(oo.vals['session_id']), {:target => '_blank'}) + end + column :latency_score do |oo| oo.vals['latency'] end + end + end + + num, objs = obj.snapshot_eligible_sessions + panel "Eligible Sessions (#{num})" do + table_for(objs) do + column :session_id do |oo| + link_to(oo.vals['session_id'], admin_music_session_path(oo.vals['session_id']), {:target => '_blank'}) + end + column :creator_id do |oo| + link_to(oo.vals['creator_id'], admin_user_path(oo.vals['creator_id']), {:target => '_blank'}) + end + column :creator_score_idx do |oo| oo.vals['creator_score_idx'] end + column :instrument_id do |oo| oo.vals['instrument_id'] end + end + end + + num, objs = obj.snapshot_eligible_recipients + panel "Eligible Recipients (#{num})" do + table_for(objs) do + column :receiver_id do |oo| + link_to(oo.vals['receiver_id'], admin_user_path(oo.vals['receiver_id']), {:target => '_blank'}) + end + column :receiver_score_idx do |oo| oo.vals['receiver_score_idx'] end + column :instrument_id do |oo| oo.vals['instrument_id'] end + end + end + end + + controller do + def new + if 0 < (max_score = params[:max_score].to_i) + ENV[EmailBatchScheduledSessions::ENV_MAX_LATENCY] = max_score.to_s + else + ENV[EmailBatchScheduledSessions::ENV_MAX_LATENCY] = '0' + end + set_resource_ivar(EmailBatchScheduledSessions.refresh_snapshot!) + render active_admin_template('show') + end + end + +end diff --git a/ruby/lib/jam_ruby/models/email_batch.rb b/ruby/lib/jam_ruby/models/email_batch.rb index 8389c56c5..06a248300 100644 --- a/ruby/lib/jam_ruby/models/email_batch.rb +++ b/ruby/lib/jam_ruby/models/email_batch.rb @@ -33,6 +33,7 @@ FOO state :delivering state :delivered state :disabled + state :snapshot event :enable do transitions :from => :disabled, :to => :pending @@ -55,6 +56,9 @@ FOO event :disable do transitions :from => [:pending, :tested, :delivered], :to => :disabled end + event :snapshoting, :after => :take_snapshot do + transitions :from => [:pending], :to => :snapshot + end end def self.new(*args) @@ -184,6 +188,9 @@ FOO self.update_with_conflict_validation({ :completed_at => Time.now }) end + def take_snapshot + end + def clone bb = EmailBatch.new bb.subject = self.subject diff --git a/ruby/lib/jam_ruby/models/email_batch_periodic.rb b/ruby/lib/jam_ruby/models/email_batch_periodic.rb index 7684528e3..98360e07b 100644 --- a/ruby/lib/jam_ruby/models/email_batch_periodic.rb +++ b/ruby/lib/jam_ruby/models/email_batch_periodic.rb @@ -5,6 +5,7 @@ module JamRuby def time_since_last_batch_query self.class .where(['created_at < ?', self.created_at]) + .where(:aasm_state => 'delivered') .order('created_at DESC') .limit(1) end diff --git a/ruby/lib/jam_ruby/models/email_batch_scheduled_sessions.rb b/ruby/lib/jam_ruby/models/email_batch_scheduled_sessions.rb index 012f7d8ee..c5df403a5 100644 --- a/ruby/lib/jam_ruby/models/email_batch_scheduled_sessions.rb +++ b/ruby/lib/jam_ruby/models/email_batch_scheduled_sessions.rb @@ -1,4 +1,24 @@ module JamRuby + + class ResultStub + extend ActiveModel::Naming + extend ActiveModel::Translation + include ActiveModel::Validations + include ActiveModel::Conversion + + attr_accessor :vals + + def initialize(vals) + @vals = vals + end + + def self.stubs(sql) + ActiveRecord::Base.connection.execute(sql).collect { |rr| self.new(rr) } + end + + def persisted?; false; end + end + class EmailBatchScheduledSessions < EmailBatchPeriodic BATCH_SIZE = 500 @@ -9,106 +29,56 @@ module JamRuby TMP_RECIP = 'tmp_candidate_recipients' TMP_MATCH = 'tmp_matches' + ENV_MAX_LATENCY = 'env_max_latency' + + def self.refresh_snapshot! + self.where(:aasm_state => 'snapshot').limit(1).first.try(:destroy) + oo = self.create + oo.snapshoting! + oo + end + def self.subject "New sessions have been scheduled that may be a good match for you!" end - # inserts eligible sessions to temp table - def _collect_eligible_sessions - ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS #{TMP_SESS}") - sql =< '#{time_since_last_batch(SINCE_DAYS)}' AND - msess.created_at < '#{self.created_at}' AND - scheduled_start >= '#{Time.now() + MIN_HOURS_START.hours}' AND - (rrrs.rsvp_slot_id IS NULL OR rrrs.chosen != 't') -SQL - ActiveRecord::Base.connection.execute(sql) + def earliest_session_create_time + time_since_last_batch(SINCE_DAYS) end - def _collect_eligible_recipients - ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS #{TMP_RECIP}") - # load eligible recipients into tmp table - sql =< offset - sql = "SELECT COUNT(DISTINCT receiver_id) AS num FROM #{TMP_MATCH}" - rr = ActiveRecord::Base.connection.execute(sql) - return 0 < rr.count ? rr[0]['num'].to_i : 0 - else - sql =< '#{earliest_session_create_time}' AND + msess.created_at < '#{latest_session_create_time}' AND + scheduled_start >= '#{earliest_session_start_time}' AND + (rrrs.rsvp_slot_id IS NULL OR rrrs.chosen != 't') +SQL + ActiveRecord::Base.connection.execute(sql) + end + + def _collect_eligible_recipients + ActiveRecord::Base.connection.execute("DROP TABLE IF EXISTS #{TMP_RECIP}") + # load eligible recipients into tmp table + sql =< offset + sql = "SELECT COUNT(DISTINCT receiver_id) AS num FROM #{TMP_MATCH}" + rr = ActiveRecord::Base.connection.execute(sql) + return 0 < rr.count ? rr[0]['num'].to_i : 0 + else + sql =< session_count, + :receiver_candidates => receiver_candidate_count, + :receiver_match => receiver_match_count + } + end + end end