From 3bc94249ca69da4ba3b372115748fc29058c7025 Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Fri, 11 Jul 2014 02:23:10 -0400 Subject: [PATCH] VRFS-1497 VRFS-1749 added resque job to clean stale sessions, added tests for session scheduler and session cleaner jobs --- db/manifest | 3 +- db/up/next_session_scheduled_default.sql | 1 + ruby/lib/jam_ruby.rb | 2 + ruby/lib/jam_ruby/models/music_session.rb | 9 +-- .../scheduled/active_music_session_cleaner.rb | 46 ++++++++++++ .../scheduled/music_session_scheduler.rb | 5 +- .../active_music_session_cleaner_spec.rb | 36 ++++++++++ .../resque/music_session_scheduler_spec.rb | 71 +++++++++++++++++++ web/config/scheduler.yml | 7 +- 9 files changed, 171 insertions(+), 9 deletions(-) create mode 100644 db/up/next_session_scheduled_default.sql create mode 100644 ruby/lib/jam_ruby/resque/scheduled/active_music_session_cleaner.rb create mode 100644 ruby/spec/jam_ruby/resque/active_music_session_cleaner_spec.rb diff --git a/db/manifest b/db/manifest index a50dbd5e0..67ef13c9e 100755 --- a/db/manifest +++ b/db/manifest @@ -188,4 +188,5 @@ fix_use_open_rsvp.sql allow_unspecified_rsvps.sql music_session_cancel_flag.sql fix_sms_query_cancel_flag.sql -fix_sms_query_cancel_flag2.sql \ No newline at end of file +fix_sms_query_cancel_flag2.sql +next_session_scheduled_default.sql \ No newline at end of file diff --git a/db/up/next_session_scheduled_default.sql b/db/up/next_session_scheduled_default.sql new file mode 100644 index 000000000..d09798c98 --- /dev/null +++ b/db/up/next_session_scheduled_default.sql @@ -0,0 +1 @@ +alter table only music_sessions alter column next_session_scheduled set default false; \ No newline at end of file diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb index 141cff16b..22c986d73 100755 --- a/ruby/lib/jam_ruby.rb +++ b/ruby/lib/jam_ruby.rb @@ -45,6 +45,8 @@ require "jam_ruby/resque/scheduled/unused_music_notation_cleaner" require "jam_ruby/resque/scheduled/user_progress_emailer" require "jam_ruby/resque/scheduled/daily_session_emailer" require "jam_ruby/resque/scheduled/new_musician_emailer" +require "jam_ruby/resque/scheduled/music_session_scheduler" +require "jam_ruby/resque/scheduled/active_music_session_cleaner" require "jam_ruby/resque/google_analytics_event" require "jam_ruby/resque/batch_email_job" require "jam_ruby/mq_router" diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb index ae4fcdec6..43c31fb0c 100644 --- a/ruby/lib/jam_ruby/models/music_session.rb +++ b/ruby/lib/jam_ruby/models/music_session.rb @@ -77,8 +77,7 @@ module JamRuby new_session.user_id = self.user_id new_session.band_id = self.band_id new_session.fan_access = self.fan_access - # TODO: confirm this logic - # new_session.scheduled_start = self.scheduled_start + self.scheduled_duration + new_session.scheduled_start = self.scheduled_start + 1.week new_session.scheduled_duration = self.scheduled_duration new_session.musician_access = self.musician_access new_session.approval_required = self.approval_required @@ -90,6 +89,8 @@ module JamRuby new_session.recurring_mode = self.recurring_mode new_session.timezone = self.timezone new_session.open_rsvps = self.open_rsvps + new_session.is_unstructured_rsvp = self.is_unstructured_rsvp + new_session.legal_terms = true # copy rsvp_slots, rsvp_requests, and rsvp_requests_rsvp_slots RsvpSlot.find_each(:conditions => "music_session_id = '#{self.id}'") do |slot| @@ -140,12 +141,12 @@ module JamRuby new_notation.user_id = notation.user_id new_notation.music_session = new_session new_notation.file_url = notation.file_url - # new_notation.file_name = notation.file_name + new_notation.file_name = notation.file_name new_notation.size = notation.size new_session.music_notations << new_notation end - new_session.save + new_session.save! # mark the next session as scheduled self.next_session_scheduled = true diff --git a/ruby/lib/jam_ruby/resque/scheduled/active_music_session_cleaner.rb b/ruby/lib/jam_ruby/resque/scheduled/active_music_session_cleaner.rb new file mode 100644 index 000000000..18722217d --- /dev/null +++ b/ruby/lib/jam_ruby/resque/scheduled/active_music_session_cleaner.rb @@ -0,0 +1,46 @@ +require 'json' +require 'resque' +require 'resque-retry' +require 'net/http' +require 'digest/md5' + +module JamRuby + + class ActiveMusicSessionCleaner + extend Resque::Plugins::LonelyJob + + attr_accessor :interval + + @queue = :active_music_session_cleaner + + @@log = Logging.logger[ActiveMusicSessionCleaner] + + def self.lock_timeout + 120 + end + + def self.perform + @@log.debug("ActiveMusicSessionCleaner waking up") + + JamWebEventMachine.run_wait_stop do + cleaner = ActiveMusicSessionCleaner.new + cleaner.interval = "INTERVAL '1 minute'" + cleaner.run + end + + @@log.debug("ActiveMusicSessionCleaner done") + end + + def run + # get all active sessions where there are no connections + stale_sessions = ActiveMusicSession.includes(:connections) + .where("active_music_sessions.updated_at < NOW() - #{self.interval}") + + stale_sessions.each do |s| + if s.connections.count == 0 + s.delete + end + end + end + end +end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/resque/scheduled/music_session_scheduler.rb b/ruby/lib/jam_ruby/resque/scheduled/music_session_scheduler.rb index 0797247eb..f54215896 100644 --- a/ruby/lib/jam_ruby/resque/scheduled/music_session_scheduler.rb +++ b/ruby/lib/jam_ruby/resque/scheduled/music_session_scheduler.rb @@ -5,7 +5,6 @@ require 'net/http' require 'digest/md5' module JamRuby - class MusicSessionScheduler extend Resque::Plugins::LonelyJob @@ -18,13 +17,13 @@ module JamRuby end def self.perform - @@log.debug("waking up") + @@log.debug("MusicSessionScheduler waking up") JamWebEventMachine.run_wait_stop do MusicSessionScheduler.new.run end - @@log.debug("done") + @@log.debug("MusicSessionScheduler done") end def run diff --git a/ruby/spec/jam_ruby/resque/active_music_session_cleaner_spec.rb b/ruby/spec/jam_ruby/resque/active_music_session_cleaner_spec.rb new file mode 100644 index 000000000..59b8b6126 --- /dev/null +++ b/ruby/spec/jam_ruby/resque/active_music_session_cleaner_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper' + +describe "ActiveMusicSessionCleaner" do + + before(:all) do + @cleaner = ActiveMusicSessionCleaner.new + @cleaner.interval = "INTERVAL '1 second'" + end + + describe "active session cleaning" do + + it "should remove active sessions that meet criteria" do + ms = FactoryGirl.create(:single_user_session) + ActiveMusicSession.all.count.should == 1 + + @cleaner.run + ActiveMusicSession.all.count.should == 1 + + # delete all connections + ms.connections.each do |c| + c.delete + end + + # hasn't been 1 minute yet + @cleaner.run + ActiveMusicSession.all.count.should == 1 + + # wait 3 seconds so the updated_at expires + sleep 3 + + @cleaner.run + ActiveMusicSession.all.count.should == 0 + + end + end +end \ No newline at end of file diff --git a/ruby/spec/jam_ruby/resque/music_session_scheduler_spec.rb b/ruby/spec/jam_ruby/resque/music_session_scheduler_spec.rb index e69de29bb..ac4d95146 100644 --- a/ruby/spec/jam_ruby/resque/music_session_scheduler_spec.rb +++ b/ruby/spec/jam_ruby/resque/music_session_scheduler_spec.rb @@ -0,0 +1,71 @@ +require 'spec_helper' + +describe "MusicSessionScheduler" do + + before(:all) do + @scheduler = MusicSessionScheduler.new + end + + describe "session scheduling" do + + it "should reschedule sessions that meet criteria" do + ms = FactoryGirl.create(:recurring_music_session_weekly) + ms.next_session_scheduled.should == false + + MusicSession.all.count.should == 1 + + @scheduler.run + + MusicSession.all.count.should == 1 + + # end the session + ms.session_removed_at = Time.now + ms.save! + + # run the scheduler again + @scheduler.run + + MusicSession.all.count.should == 2 + + MusicSession.where(:session_removed_at => nil).count.should == 1 + MusicSession.where(:next_session_scheduled => true).count.should == 1 + end + + it "should not reschedule session that does not meet criteria" do + # test non-recurring session + ms = FactoryGirl.create(:music_session) + + MusicSession.all.count.should == 1 + + @scheduler.run + MusicSession.all.count.should == 1 + + ms.session_removed_at = Time.now + ms.save! + + @scheduler.run + MusicSession.all.count.should == 1 + + # test canceled session + ms = FactoryGirl.create(:recurring_music_session_weekly) + MusicSession.all.count.should == 2 + + ms.canceled = true + ms.save! + + @scheduler.run + MusicSession.all.count.should == 2 + + # test already rescheduled + ms = FactoryGirl.create(:recurring_music_session_weekly) + ms.next_session_scheduled = true + ms.save! + + MusicSession.all.count.should == 3 + + @scheduler.run + MusicSession.all.count.should == 3 + + end + end +end \ No newline at end of file diff --git a/web/config/scheduler.yml b/web/config/scheduler.yml index 87753a1f4..865c01813 100644 --- a/web/config/scheduler.yml +++ b/web/config/scheduler.yml @@ -42,4 +42,9 @@ NewMusicianEmailer: MusicSessionScheduler: cron: "0 */5 0 * *" class: "JamRuby::MusicSessionScheduler" - description: "Schedules music sessions that are marked as recurring" \ No newline at end of file + description: "Schedules music sessions that are marked as recurring" + +ActiveMusicSessionCleaner: + cron: "0 */5 0 * *" + class: "JamRuby::ActiveMusicSessionCleaner" + description: "Removes any active music sessions that are stale." \ No newline at end of file