From dac291000885f4461bbaf3435fb00f2bd081085d Mon Sep 17 00:00:00 2001 From: Seth Call Date: Tue, 28 Oct 2014 21:16:54 -0500 Subject: [PATCH] * VRFS-2400 - show retry button only in the correct conditions * VRFS-2425 - make sure threads don't die on exception, but report up --- .../assets/javascripts/sync_viewer.js.coffee | 43 +++++++++++++++---- .../assets/stylesheets/client/common.css.scss | 6 +-- .../lib/jam_websockets/server.rb | 21 +++++++-- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/web/app/assets/javascripts/sync_viewer.js.coffee b/web/app/assets/javascripts/sync_viewer.js.coffee index 1a749aa3d..4be93ba13 100644 --- a/web/app/assets/javascripts/sync_viewer.js.coffee +++ b/web/app/assets/javascripts/sync_viewer.js.coffee @@ -220,6 +220,7 @@ context.JK.SyncViewer = class SyncViewer updateTrackState: ($track) => clientInfo = $track.data('client-info') serverInfo = $track.data('server-info') + myTrack = serverInfo.user.id == context.JK.currentUserId # determine client state clientStateMsg = 'UNKNOWN' @@ -261,7 +262,7 @@ context.JK.SyncViewer = class SyncViewer uploadStateClass = 'error' uploadState = @uploadStates.too_many_upload_failures else - if serverInfo.user.id == context.JK.currentUserId + if myTrack if clientInfo? if clientInfo.local_state == 'HQ' uploadStateMsg = 'PENDING UPLOAD' @@ -282,7 +283,7 @@ context.JK.SyncViewer = class SyncViewer else uploadStateMsg = 'UPLOADED' uploadStateClass = 'uploaded' - if serverInfo.user.id == context.JK.currentUserId + if myTrack uploadState = @uploadStates.me_uploaded else uploadState = @uploadStates.them_uploaded @@ -301,6 +302,30 @@ context.JK.SyncViewer = class SyncViewer $uploadStateMsg.text(uploadStateMsg) $uploadStateProgress.css('width', '0') + # this allows us to make styling decisions based on the combination of both client and upload state. + $track.addClass("clientState-#{clientStateClass}").addClass("uploadState-#{uploadStateClass}") + + $clientRetry = $clientState.find('.retry') + $uploadRetry = $uploadState.find('.retry') + + if gon.isNativeClient + # handle client state + + # only show RETRY button if you have a SQ or if it's missing, and it's been uploaded already + if (clientState == @clientStates.sq or clientState == @clientStates.missing) and (uploadState == @uploadStates.me_uploaded or uploadState == @uploadStates.them_uploaded) + $clientRetry.show() + else + $clientRetry.hide() + + # only show RETRY button if you have the HQ track, it's your track, and the server doesn't yet have it + if myTrack and @clientStates.hq and (uploadState == @uploadStates.error or uploadState == @uploadStates.me_upload_soon) + $uploadRetry.show() + else + $uploadRetry.hide() + else + $clientRetry.hide() + $uploadRetry.hide() + associateClientInfo: (recording) => for clientInfo in recording.local_tracks $track = @list.find(".recorded-track[data-recording-id='#{recording.recording_id}'][data-client-track-id='#{clientInfo.client_track_id}']") @@ -511,14 +536,16 @@ context.JK.SyncViewer = class SyncViewer $track.data('sync-viewer', this) $clientState = $track.find('.client-state') $uploadState = $track.find('.upload-state') - $clientState.find('.retry').click(this.retryDownloadRecordedTrack) - $uploadState.find('.retry').click(this.retryUploadRecordedTrack) + $clientStateRetry = $clientState.find('.retry') + $clientStateRetry.click(this.retryDownloadRecordedTrack) + $uploadStateRetry = $uploadState.find('.retry') + $uploadStateRetry.click(this.retryUploadRecordedTrack) context.JK.bindHoverEvents($track) context.JK.bindInstrumentHover($track, {positions:['top'], shrinkToFit: true}); context.JK.hoverBubble($clientState, this.onHoverOfStateIndicator, {width:'450px', closeWhenOthersOpen: true, positions:['left']}) context.JK.hoverBubble($uploadState, this.onHoverOfStateIndicator, {width:'450px', closeWhenOthersOpen: true, positions:['right']}) - $clientState.addClass('is-native-client') if context.jamClient.IsNativeClient() - $uploadState.addClass('is-native-client') if context.jamClient.IsNativeClient() + $clientState.addClass('is-native-client') if gon.isNativeClient + $uploadState.addClass('is-native-client') if gon.isNativeClient $track createStreamMix: (userSync) => @@ -530,8 +557,8 @@ context.JK.SyncViewer = class SyncViewer $uploadState.find('.retry').click(this.retryUploadRecordedTrack) context.JK.hoverBubble($clientState, this.onStreamMixHover, {width:'450px', closeWhenOthersOpen: true, positions:['left']}) context.JK.hoverBubble($uploadState, this.onStreamMixHover, {width:'450px', closeWhenOthersOpen: true, positions:['right']}) - $clientState.addClass('is-native-client') if context.jamClient.IsNativeClient() - $uploadState.addClass('is-native-client') if context.jamClient.IsNativeClient() + $clientState.addClass('is-native-client') if gon.isNativeClient + $uploadState.addClass('is-native-client') if gon.isNativeClient $track exportRecording: (e) => diff --git a/web/app/assets/stylesheets/client/common.css.scss b/web/app/assets/stylesheets/client/common.css.scss index 93183a836..e2f174fe0 100644 --- a/web/app/assets/stylesheets/client/common.css.scss +++ b/web/app/assets/stylesheets/client/common.css.scss @@ -180,6 +180,7 @@ $fair: #cc9900; @mixin client-state-box { + .client-state { position:relative; text-align:center; @@ -193,7 +194,6 @@ $fair: #cc9900; &.error { background-color: $error; - &.is-native-client { .retry { display:inline-block; } } } &.hq { @@ -202,12 +202,10 @@ $fair: #cc9900; &.sq { background-color: $good; - &.is-native-client { .retry { display:inline-block; } } } &.missing { background-color: $error; - &.is-native-client { .retry { display:inline-block; } } } &.discarded { @@ -240,7 +238,6 @@ $fair: #cc9900; &.error { background-color: $error; - &.is-native-client { .retry { display:inline-block; } } } &.missing { @@ -249,7 +246,6 @@ $fair: #cc9900; &.upload-soon { background-color: $fair; - &.is-native-client { .retry { display:inline-block; } } } &.uploaded { diff --git a/websocket-gateway/lib/jam_websockets/server.rb b/websocket-gateway/lib/jam_websockets/server.rb index f03ecf11e..9d27ea040 100644 --- a/websocket-gateway/lib/jam_websockets/server.rb +++ b/websocket-gateway/lib/jam_websockets/server.rb @@ -80,7 +80,7 @@ module JamWebsockets @router.periodical_check_connections EventMachine::PeriodicTimer.new(2) do - sane_logging { @router.periodical_check_connections } + safety_net { sane_logging { @router.periodical_check_connections } } end end @@ -89,7 +89,7 @@ module JamWebsockets @router.periodical_check_clients EventMachine::PeriodicTimer.new(30) do - sane_logging { @router.periodical_check_clients } + safety_net { sane_logging { @router.periodical_check_clients } } end end @@ -98,16 +98,29 @@ module JamWebsockets @router.periodical_flag_connections EventMachine::PeriodicTimer.new(2) do - sane_logging { @router.periodical_flag_connections } + safety_net { sane_logging { @router.periodical_flag_connections } } end end def start_stats_dump EventMachine::PeriodicTimer.new(60) do - @router.periodical_stats_dump + safety_net { @router.periodical_stats_dump } end end + # this was added for this reason: https://jamkazam.atlassian.net/browse/VRFS-2425 + # if an unhandled exception occurs in PeriodicTimer, it just kills all future timers; doesn't kill the app. + # not really what you want. + + # so, we signal to Bugsnag, so we know really bad stuff is happening, but we also move + def safety_net(&blk) + begin + blk.call + rescue => e + Bugsnag.notify(e) + @log.error("unhandled exception in EM Timer #{e}") + end + end def sane_logging(&blk) # used around repeated transactions that cause too much ActiveRecord::Base logging # example is handling heartbeats