optimize session query and catch dead connection in websocket gateway; heal dbconn

This commit is contained in:
Seth Call 2017-10-08 10:43:33 -05:00
parent 779b8e5c92
commit d3e787fb2a
3 changed files with 213 additions and 1 deletions

View File

@ -377,3 +377,4 @@ guitar_center_integration_v1.sql
mobile_recording_support.sql mobile_recording_support.sql
youtube_broadcast.sql youtube_broadcast.sql
amazon_v1.sql amazon_v1.sql
sms_index_optimize.sql

View File

@ -0,0 +1,206 @@
-- 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, session_id VARCHAR, include_pending BOOLEAN DEFAULT FALSE) 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;
IF session_id = 'any' THEN
-- 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 description != 'Jam Track Session'
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;
ELSE
INSERT INTO sms_music_session_tmp SELECT DISTINCT id, NULL::INTEGER AS tag, NULL::INTEGER AS latency
FROM music_sessions
WHERE music_sessions.id = session_id;
END IF;
-- 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, full_score INTEGER, audio_latency INTEGER, internet_score INTEGER) ON COMMIT DROP;
IF my_audio_latency > -1 THEN
IF include_pending 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 DISTINCT q.music_session_id, users.id, s.full_score AS full_score, s.a_audio_latency, s.score
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.a_userid = users.id
WHERE
s.b_userid = my_user_id;
-- 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.full_score AS full_score, s.a_audio_latency, s.score
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.a_userid = users.id
WHERE
s.b_userid = my_user_id AND
users.id NOT IN (SELECT user_id FROM sms_users_tmp);
ELSE
-- 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 DISTINCT q.music_session_id, users.id, s.full_score AS full_score, s.a_audio_latency, s.score
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.a_userid = users.id
WHERE
s.b_userid = my_user_id AND
rsvp_requests_rsvp_slots.chosen = TRUE AND
rsvp_requests.canceled != TRUE;
END IF;
END IF;
-- calculate the average latency
UPDATE sms_music_session_tmp q SET latency = (select AVG(u.full_score) FROM sms_users_tmp u WHERE
q.music_session_id = u.music_session_id);
RETURN;
END;
$$ LANGUAGE plpgsql;
-- check that the music_sessions does not currently have an active_music_sessions
CREATE OR REPLACE FUNCTION sms_index_test (my_user_id VARCHAR, my_locidispid BIGINT, my_audio_latency INTEGER, session_id VARCHAR, include_pending BOOLEAN DEFAULT FALSE) 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;
IF session_id = 'any' THEN
-- 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 description != 'Jam Track Session'
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;
ELSE
INSERT INTO sms_music_session_tmp SELECT DISTINCT id, NULL::INTEGER AS tag, NULL::INTEGER AS latency
FROM music_sessions
WHERE music_sessions.id = session_id;
END IF;
-- 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, full_score INTEGER, audio_latency INTEGER, internet_score INTEGER) ON COMMIT DROP;
IF my_audio_latency > -1 THEN
IF include_pending 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 DISTINCT q.music_session_id, users.id, CAST(NULL AS INTEGER), CAST(NULL AS INTEGER), CAST(NULL AS INTEGER)
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;
-- 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, CAST(NULL AS INTEGER), CAST(NULL AS INTEGER), CAST(NULL AS INTEGER)
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
WHERE
users.id NOT IN (SELECT user_id FROM sms_users_tmp);
ELSE
-- 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 DISTINCT q.music_session_id, users.id, CAST(NULL AS INTEGER), CAST(NULL AS INTEGER), CAST(NULL AS INTEGER)
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
WHERE
rsvp_requests_rsvp_slots.chosen = TRUE AND
rsvp_requests.canceled != TRUE;
END IF;
END IF;
-- calculate the average latency
--UPDATE sms_music_session_tmp q SET latency = (select AVG(u.full_score) FROM sms_users_tmp u WHERE
-- q.music_session_id = u.music_session_id);
RETURN;
END;
$$ LANGUAGE plpgsql;
-- XXXX TODO: TURN THESE ON AFTER PRODUCTION IS UPDATED
-- CREATE INDEX index_rsvp_requests_rsvp_slots_on_rsvp_request_id ON rsvp_requests_rsvp_slots USING btree(rsvp_request_id);
-- CREATE INDEX index_rsvp_requests_rsvp_slots_on_rsvp_slot_id ON rsvp_requests_rsvp_slots USING btree(rsvp_slot_id);
-- CREATE INDEX index_rsvp_requests_rsvp_slots_on_chosen ON rsvp_requests_rsvp_slots USING btree(chosen);
-- CREATE INDEX index_rsvp_slots_on_music_session_id ON rsvp_slots USING btree(music_session_id);
-- CREATE INDEX index_rsvp_requests_user_id ON rsvp_requests USING btree(user_id);
-- CREATE INDEX index_rsvp_requests_canceled ON rsvp_requests USING btree(canceled);
-- CREATE INDEX index_invitations_on_receiver_id ON invitations USING btree(receiver_id);
-- CREATE INDEX index_invitations_on_music_session_id ON invitations USING btree(music_session_id);
-- select sms_index_test('062deeba-b917-46e2-bfa3-e829405ca602'::varchar, 26880045373::bigint, 18.911563873291::integer, 'any'::varchar, false::boolean)
-- update music_sessions set canceled = true WHERE (scheduled_start IS NULL OR scheduled_start > (NOW() - (interval '15 minute'))) AND canceled = FALSE AND description != 'Jam Track Session' AND id NOT IN (SELECT id FROM active_music_sessions) AND id NOT IN (select distinct on(name, user_id) id FROM music_sessions WHERE (scheduled_start IS NULL OR scheduled_start > (NOW() - (interval '15 minute'))) AND canceled = FALSE AND description != 'Jam Track Session' AND id NOT IN (SELECT id FROM active_music_sessions) order by name, user_id);
-- select distinct on(name, user_id) name, description, scheduled_start FROM music_sessions WHERE (scheduled_start IS NULL OR scheduled_start > (NOW() - (interval '15 minute'))) AND canceled = FALSE AND description != 'Jam Track Session' AND id NOT IN (SELECT id FROM active_music_sessions) order by name, user_id;
-- get count
-- SELECT count(id) FROM music_sessions WHERE (scheduled_start IS NULL OR scheduled_start > (NOW() - (interval '15 minute'))) AND canceled = FALSE AND description != 'Jam Track Session' AND id NOT IN (SELECT id FROM active_music_sessions)

View File

@ -412,6 +412,11 @@ module JamWebsockets
@log.error "ending client session due to server programming or runtime error. reason=#{e.to_s}" @log.error "ending client session due to server programming or runtime error. reason=#{e.to_s}"
@log.error e @log.error e
if PG::UnableToSend
# indicates connection to server is down; kill self. Will be restarted; if db is up we will be healthy
@log.error "EXITING DUE TO DEAD DBCONN"
Kernel.exit!(1)
end
begin begin
# wrap the message up and send it down # wrap the message up and send it down
error_msg = @message_factory.server_generic_error(e.to_s) error_msg = @message_factory.server_generic_error(e.to_s)