diff --git a/db/manifest b/db/manifest index fa5f268a8..58d338b79 100755 --- a/db/manifest +++ b/db/manifest @@ -192,4 +192,6 @@ fix_sms_query_cancel_flag2.sql next_session_scheduled_default.sql migrate_old_sessions.sql max_mind_releases.sql -score_histories.sql \ No newline at end of file +score_histories.sql +update_sms_index.sql +connection_allow_null_locidispid.sql \ No newline at end of file diff --git a/db/up/connection_allow_null_locidispid.sql b/db/up/connection_allow_null_locidispid.sql new file mode 100644 index 000000000..c6139cf8c --- /dev/null +++ b/db/up/connection_allow_null_locidispid.sql @@ -0,0 +1 @@ +ALTER TABLE connections ALTER COLUMN locidispid DROP NOT NULL; \ No newline at end of file diff --git a/db/up/update_sms_index.sql b/db/up/update_sms_index.sql new file mode 100644 index 000000000..d46682f0c --- /dev/null +++ b/db/up/update_sms_index.sql @@ -0,0 +1,73 @@ +-- check that the music_sessions does not currently have an active_music_sessions +CREATE OR REPLACE FUNCTION sms_index (my_user_id VARCHAR, my_locidispid BIGINT, my_audio_latency INTEGER) RETURNS VOID STRICT VOLATILE AS $$ + BEGIN + -- output table to hold tagged music sessions with latency + CREATE TEMPORARY TABLE sms_music_session_tmp (music_session_id VARCHAR(64) NOT NULL, tag INTEGER, latency INTEGER) ON COMMIT DROP; + + -- populate sms_music_session_tmp as all music sessions + -- XXX: we should pass in enough info to match pagination/query to reduce the impact of this step + INSERT INTO sms_music_session_tmp SELECT DISTINCT id, NULL::INTEGER AS tag, NULL::INTEGER AS latency + FROM music_sessions + WHERE (scheduled_start IS NULL OR scheduled_start > (NOW() - (interval '15 minute'))) + AND canceled = FALSE + AND id NOT IN (SELECT id FROM active_music_sessions); + + -- tag accepted rsvp as 1 + UPDATE sms_music_session_tmp q SET tag = 1 FROM rsvp_slots s, rsvp_requests_rsvp_slots rrs, rsvp_requests r WHERE + q.music_session_id = s.music_session_id AND + s.id = rrs.rsvp_slot_id AND + rrs.rsvp_request_id = r.id AND + r.user_id = my_user_id AND + rrs.chosen = TRUE AND + q.tag is NULL; + + -- tag invitation as 2 + UPDATE sms_music_session_tmp q SET tag = 2 FROM invitations i WHERE + q.music_session_id = i.music_session_id AND + i.receiver_id = my_user_id AND + q.tag IS NULL; + + -- musician access as 3 + UPDATE sms_music_session_tmp q SET tag = 3 FROM music_sessions m WHERE + q.music_session_id = m.id AND + m.open_rsvps = TRUE AND + q.tag IS NULL; + + -- delete anything not tagged + DELETE FROM sms_music_session_tmp WHERE tag IS NULL; + + -- output table to hold users involved in the sms_music_session_tmp sessions and their latency + CREATE TEMPORARY TABLE sms_users_tmp (music_session_id VARCHAR(64), user_id VARCHAR(64) NOT NULL, latency INTEGER) ON COMMIT DROP; + + IF my_audio_latency > -1 THEN + -- populate sms_users_tmp with users that have an approved RSVP for sessions in the sms_music_session_tmp table, accompanied with full latency and music session + INSERT INTO sms_users_tmp SELECT q.music_session_id, users.id, (s.score+my_audio_latency+users.last_jam_audio_latency)/2 AS latency + FROM sms_music_session_tmp q + INNER JOIN rsvp_slots ON rsvp_slots.music_session_id = q.music_session_id + INNER JOIN rsvp_requests_rsvp_slots ON rsvp_requests_rsvp_slots.rsvp_slot_id = rsvp_slots.id + INNER JOIN rsvp_requests ON rsvp_requests.id = rsvp_requests_rsvp_slots.rsvp_request_id + INNER JOIN users ON rsvp_requests.user_id = users.id + LEFT OUTER JOIN current_scores s ON s.alocidispid = users.last_jam_locidispid + WHERE + s.blocidispid = my_locidispid AND + rsvp_requests_rsvp_slots.chosen = TRUE; + + -- populate sms_users_tmp with invited users for session in the sms_music_session_tmp table, accompanied with full latency and music session + -- specify NULL for music_session_id, because we don't want RSVP users to affect the AVG computed for each session later + INSERT INTO sms_users_tmp SELECT NULL, users.id, (s.score+my_audio_latency+users.last_jam_audio_latency)/2 AS latency + FROM sms_music_session_tmp q + INNER JOIN invitations ON invitations.music_session_id = q.music_session_id + INNER JOIN users ON invitations.receiver_id = users.id + LEFT OUTER JOIN current_scores s ON s.alocidispid = users.last_jam_locidispid + WHERE + s.blocidispid = my_locidispid AND + users.id NOT IN (SELECT user_id FROM sms_users_tmp); + END IF; + + -- calculate the average latency + UPDATE sms_music_session_tmp q SET latency = (select AVG(u.latency) FROM sms_users_tmp u WHERE + q.music_session_id = u.music_session_id); + + RETURN; + END; +$$ LANGUAGE plpgsql; \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/active_music_session.rb b/ruby/lib/jam_ruby/models/active_music_session.rb index 8d57278b6..edc98fd9f 100644 --- a/ruby/lib/jam_ruby/models/active_music_session.rb +++ b/ruby/lib/jam_ruby/models/active_music_session.rb @@ -325,8 +325,9 @@ module JamRuby my_locidispid = connection.locidispid # 13 is an average audio gear value we use if they have not qualified any gear my_audio_latency = connection.last_jam_audio_latency || current_user.last_jam_audio_latency || 13 + locidispid_expr = my_locidispid ? "#{my_locidispid}::bigint" : '0::bigint' - self.connection.execute("select ams_index('#{current_user.id}'::varchar, #{my_locidispid}::bigint, #{my_audio_latency}::integer)"); + self.connection.execute("select ams_index('#{current_user.id}'::varchar, #{locidispid_expr}, #{my_audio_latency}::integer)").check end # Generate a list of music sessions (that are active) filtered by genre, language, keyword, and sorted diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb index c5dfb2c68..271bd5863 100644 --- a/ruby/lib/jam_ruby/models/music_session.rb +++ b/ruby/lib/jam_ruby/models/music_session.rb @@ -242,7 +242,6 @@ module JamRuby def self.scheduled user query = MusicSession.where("music_sessions.canceled = FALSE") - query = query.where("music_sessions.started_at IS NULL") query = query.where("music_sessions.user_id = '#{user.id}'") query = query.where("music_sessions.scheduled_start IS NULL OR music_sessions.scheduled_start > NOW() - '12 hour'::INTERVAL") query = query.order("music_sessions.scheduled_start ASC") @@ -588,8 +587,9 @@ module JamRuby my_locidispid = connection.locidispid # 13 is an average audio gear value we use if they have not qualified any gear my_audio_latency = connection.last_jam_audio_latency || current_user.last_jam_audio_latency || 13 + locidispid_expr = my_locidispid ? "#{my_locidispid}::bigint" : '0::bigint' # Have to pass in zero; NULL fails silently in the stored proc - self.connection.execute("select sms_index('#{current_user.id}'::varchar, #{my_locidispid}::bigint, #{my_audio_latency}::integer)"); + self.connection.execute("SELECT sms_index('#{current_user.id}'::varchar, #{locidispid_expr}, #{my_audio_latency}::integer)").check end # Generate a list of music sessions (that are active) filtered by genre, language, keyword, and sorted diff --git a/ruby/spec/jam_ruby/models/active_music_session_spec.rb b/ruby/spec/jam_ruby/models/active_music_session_spec.rb index 476a35420..b59dd0b45 100644 --- a/ruby/spec/jam_ruby/models/active_music_session_spec.rb +++ b/ruby/spec/jam_ruby/models/active_music_session_spec.rb @@ -503,6 +503,14 @@ describe ActiveMusicSession do music_sessions.length.should == 1 music_sessions[0].should == music_session_1.music_session end + + it "should allow a null locidispid to search" do + searcher_conn_1.locidispid = nil + searcher_conn_1.save! + music_sessions, user_scores = ams(searcher_1, client_id: searcher_conn_1.client_id) + music_sessions.length.should == 2 + + end end # todo we need more tests: diff --git a/ruby/spec/jam_ruby/models/music_session_spec.rb b/ruby/spec/jam_ruby/models/music_session_spec.rb index 7071578ed..da8692250 100644 --- a/ruby/spec/jam_ruby/models/music_session_spec.rb +++ b/ruby/spec/jam_ruby/models/music_session_spec.rb @@ -518,6 +518,30 @@ describe MusicSession do user_scores.length.should == 1 # the creator, and the invitee user_scores[creator.id][:latency].should == ((network_score + invitee.last_jam_audio_latency + creator.last_jam_audio_latency ) / 2).ceil end + + it "does not show when it goes active" do + # we create a scheduled session--it should return + music_session = FactoryGirl.create(:music_session, creator: creator, scheduled_start: nil) + music_sessions, user_scores = sms(searcher, default_opts) + music_sessions.length.should == 1 + + # but then make an active session for this scheduled session + ams = FactoryGirl.create(:active_music_session, music_session: music_session, creator: creator, musician_access: true) + music_sessions, user_scores = sms(searcher, default_opts) + music_sessions.length.should == 0 + + # finally, delete the active session, and see results go back to one + ams.delete + music_sessions, user_scores = sms(searcher, default_opts) + music_sessions.length.should == 1 + end + + it "should allow a null locidispid to search" do + searcher_conn.locidispid = nil + searcher_conn.save! + music_sessions, user_scores = sms(searcher, default_opts) + music_sessions.length.should == 0 + end end diff --git a/web/app/assets/javascripts/findSession.js b/web/app/assets/javascripts/findSession.js index e5b9c417b..fca452cc9 100644 --- a/web/app/assets/javascripts/findSession.js +++ b/web/app/assets/javascripts/findSession.js @@ -9,6 +9,7 @@ SCHEDULED: {index: 1, id: "table#sessions-scheduled"} }; + var $screen = null; var $dateFilter = $("#session-date-filter"); var $sessionLanguageFilter = $('#session-language-filter'); @@ -16,15 +17,14 @@ var rest = context.JK.Rest(); var sessionList; - var LIMIT = 10; + var ACTIVE_SESSIONS_LIMIT = 50; + var SCHEDULED_SESSIONS_LIMIT = 20; - var $asNext = null; - var $asScroller = null; - var currentActiveSessionsPage = 0; var currentActiveSessionsQuery = defaultActiveSessionsQuery(); var $ssNext = null; var $ssScroller = null; + var $ssNoMoreEntries = null; var currentScheduledSessionsPage = 0; var currentScheduledSessionsQuery = defaultScheduledSessionsQuery(); @@ -90,7 +90,7 @@ /***************** ACTIVE SESSIONS *****************/ function defaultActiveSessionsQuery() { - return {offset:currentActiveSessionsPage * LIMIT, limit:LIMIT, page:currentActiveSessionsPage}; + return {offset:0, limit:SCHEDULED_SESSIONS_LIMIT, page:0}; } function renderActiveSessions(sessions) { @@ -98,6 +98,7 @@ sessionList.renderActiveSession(session, $(CATEGORY.ACTIVE.id)); }); + afterLoadActiveSessions(sessions); } @@ -141,7 +142,7 @@ var $noSessionsMsgSelector = $('#no-active-sessions'); - if (sessionList.length === 0 && currentActiveSessionsPage === 0) { + if (sessionList.length === 0) { $(CATEGORY.ACTIVE.id).hide(); $noSessionsMsgSelector.show(); } @@ -150,45 +151,15 @@ $noSessionsMsgSelector.hide(); } - if(sessionList.length < LIMIT) { - // if we retrieve less results than asked for, end searching - $asScroller.infinitescroll('pause'); - } - else { - currentActiveSessionsPage++; - buildActiveSessionsQuery(); - registerActiveSessionInfiniteScroll(); - } + buildActiveSessionsQuery(); context.JK.GA.trackFindSessions(sessionList.length); } - function registerActiveSessionInfiniteScroll() { - $asScroller.infinitescroll({ - behavior: 'local', - navSelector: '#sessions-active .btn-next-wrapper', - nextSelector: '#sessions-active .btn-next', - binder: $asScroller, - dataType: 'json', - appendCallback: false, - debug: true, - prefill: false, - bufferPx:100, - loading: { - msg: $('