This commit is contained in:
Seth Call 2015-01-11 15:42:12 -06:00
parent 5ac69fc646
commit 4d8a7a9bc1
5 changed files with 249 additions and 22 deletions

View File

@ -123,8 +123,6 @@ module JamRuby
state = nil
if signed
state = 'SIGNED'
elsif error_count > 0
state = 'ERROR'
elsif signing_started_at
if Time.now - signing_started_at > APP_CONFIG.signing_job_run_max_time
state = 'SIGNING_TIMEOUT'
@ -137,6 +135,8 @@ module JamRuby
else
state = 'QUEUED'
end
elsif error_count > 0
state = 'ERROR'
else
state = 'QUIET' # needs to be poked to go build
end

View File

@ -9,46 +9,239 @@ context.JK ||= {};
# The JamTrack exists on the server, but not on disk, so we will download it (downloading state)
# The JamTrack is on the disk, but does not yet have keys, so we will fetch them (keying)
context.JK.DownloadJamTracks = {}
context.JK.DownloadJamTrack = class DownloadJamTrack
constructor: (@app) ->
constructor: (@app, jamTrackId, jamTrackRightId) ->
@EVENTS = context.JK.EVENTS
@rest = context.JK.Rest()
@jamTrackId = null
@logger = context.JK.logger
@jamTrackId = jamTrackId
@jamTrackRightId = jamTrackRightId
@attemptedEnqueue = false
@errorMessage = null
@transitionTimer = null
@downloadTimer = null
@trackDetail = null
@errorSupportMsg = "Press RETRY, or if you have already retried, please contact support@jamkazam.com."
@states = {
synchronized: 'synchronized',
packaging: 'packaging',
downloading: 'downloading',
keying: 'keying',
initial: 'initial'
no_client: { name: 'no-client', show: @showNoClient },
synchronized: { name: 'synchronized', show: @showSynchronized },
packaging: { name: 'packaging', show: @showPackaging },
downloading: { name: 'downloading', show: @showDownloading },
keying: { name: 'keying', show: @showKeying },
initial: { name: 'initial', show: @showInitial },
errored: { name: 'errored', show: @showError }
}
@state = @states.initial
init: (jamTrackId) =>
@jamTrackId = jamTrackId
@root = $($('#template-download-jamtrack').html())
context.JK.DownloadJamTracks[@jamTrackId] = this
# after you've created the DownloadJamTrack widget, call synchronize which will begin ensuring that the jamtrack
# is downloaded and ready to open
synchronize: () =>
init: () =>
@root = $($('#template-download-jamtrack').html())
# populate in template and visual transition functions
for state, data of @states
data.template = $("#template-download-jamtrack-state-#{data.name}")
# check if we are in a browser or client
if !gon.isNativeClient
@states.no_client.show()
else
@states.initial.show()
this.synchronize()
@attemptedEnqueue = false
this.checkState()
showPackaging: () =>
@logger.debug("showing #{@states.name}")
showDownloading: () =>
@logger.debug("showing #{@states.name}")
# while downloading, we don't run the transition timer, because the download API is guaranteed to call success, or failure, eventually
this.clearTransitionTimer()
context.jamClient.StartFileDownload(context.JK.makeAbsolute('/api/jamtracks/download/' + @jamTrackId), this.makeDownloadProgressCallback(), this.makeDownloadSuccessCallback(), this.makeDownloadFailureCallback(), true)
showKeying: () =>
@logger.debug("showing #{@states.name}")
this.clearTransitionTimer()
context.jamClient.requestJamTrackKeys()
this.expectKeyed()
showInitial: () =>
@logger.debug("showing #{@states.name}")
context.JK.SubscriptionUtils.subscribe('jam_track_right', @jamTrackRightId).on(context.JK.EVENTS.SUBSCRIBE_NOTIFICATION, this.onJamTrackRightEvent)
showError: () =>
@logger.debug("showing #{@states.name}")
clearTransitionTimer()
context.JK.SubscriptionUtils.unsubscribe('jam_track_right', @jamTrackRightId)
showSynchronized: () =>
@logger.debug("showing #{@states.name}")
clearTransitionTimer()
context.JK.SubscriptionUtils.unsubscribe('jam_track_right', @jamTrackRightId)
showNoClient: () =>
@logger.debug("showing #{@states.name}")
downloadCheck: () =>
@logger.debug "downloadcheck"
# sets an interval timer for every 3 seconds, waiting for the status to change
expectKeyed: () =>
expectDownload: () =>
unless @downloadTimer?
return
# every 10 seconds, wake up and check the server and see if we missed a state transition
this.clearDownloadTimer()
@downloadTimer = setTimeout(this.downloadCheck, 10000)
clearDownloadTimer: () =>
if @downloadTimer?
clearTimeout(@downloadTimer)
@downloadTimer = null
transitionCheck: () =>
this.checkState()
# this should be called every time something changes statefully, to restart a 12 second timer to hit the server for update.
# if everything is moving snappily, we won't have to query the server much, because we are also getting subscription events
# about any changes to the status of the jam track. But, we could miss a message or there could be a path in the server where
# we don't get an event, so that's why, after 12 seconds, we'll still go to the server and check.
# exception: this should not be runngi
expectTransition: () =>
unless @transitionTimer?
return
# every 12 seconds, wake up and check the server and see if we missed a state transition
this.clearTransitionTimer()
@transitionTimer = setTimeout(this.transitionCheck, 12000)
clearTransitionTimer: () =>
if @transitionTimer?
clearTimeout(@transitionTimer)
@transitionTimer = null
transition: (newState) =>
if newState == @state
@logger.debug("DownloadJamTrack: ignoring state change #{@state}")
return
@logger.debug("DownloadJamTrack: state change: #{@state} => #{newState}")
@state = newState
@states[newState].show()
checkState: () =>
isPlayable = context.jamClient.JamTrackIsPlayable()
# check for the success state against the local state of the client... if it's playable, then we should be OK
@trackDetail = context.jamClient.JamTrackGetTrackDetail(@jamTrackId)
if isPlayable
this.transition(@states.synchronized)
else
switch @trackDetail.key_state
when 'pending'
this.transition(@states.keying)
when 'not authorized'
this.transition(@states.keying)
when 'ready'
this.transition(@states.synchronized)
when 'unknown'
@rest.getJamTrackRight({id: @jamTrackId})
.done(this.processJamTrackRight)
.fail(this.processJamTrackRightFail)
@rest.getJamTrackRight({id: @jamTrackId})
.done(this.processJamTrackRight)
.fail(@app.ajaxError)
processSigningState: (signingState) =>
switch signingState
when 'QUIET'
if @attemptedEnqueue
# this means we've already tried to poke the server. something is wrong
@errorMessage = "The server has not begun building your JamTrack. #{@errorSupportMsg}"
this.transition(@states.errored)
else
this.expectTransition()
@rest.enqueueJamTrack({id: @jamTrackId})
.done(this.processEnqueueJamTrack)
.fail(this.processEnqueueJamTrackFail)
when 'QUEUED'
# when it's queued, there is nothing to do except wait.
this.expectTransition()
this.transition(@states.packaging)
when 'QUEUED_TIMEOUT'
@errorMessage = "The server took too long to begin processing your JamTrack. #{@errorSupportMsg}"
this.transition(@states.errored)
when 'SIGNING'
this.expectTransition()
when 'SIGNING_TIMEOUT'
@errorMessage = "The server took too long to create your JamTrack. #{@errorSupportMsg}"
this.transition(@states.errored)
when 'SIGNED'
this.transition(@states.downloading)
when 'ERROR'
if @attemptedEnqueue
# this means we've already tried to poke the server. something is wrong
@errorMessage = "The server failed to create your package. #{@errorSupportMsg}"
this.transition(@states.errored)
else
this.expectTransition()
@rest.enqueueJamTrack({id: @jamTrackId})
.done(this.processEnqueueJamTrack)
.fail(this.processEnqueueJamTrackFail)
processJamTrackRightFail: () =>
@errorMessage = "Unable to check with the server on the status of your JamTrack. #{@errorSupportMsg}"
this.transition(@states.errored)
processEnqueueJamTrack: (enqueueResponse) =>
this.expectTransition() # the act of enqueuing should send down events to the client. we wait...
processEnqueueJamTrackFail: () =>
@errorMessage = "Unable to ask the server to build your JamTrack. #{@errorSupportMsg}"
this.transition(@states.errored)
processJamTrackRight: (myJamTrack) =>
if response.signing_state
this.processSigningState(myJamTrack.signing_state)
onJamTrackRightEvent: (e, data) =>
@logger.debug("DownloadJamTrack: subscription notification received: type:" + data.type)
this.expectTransition()
this.processSigningState(data.body.signing_state)
downloadProgressCallback: (bytesReceived, bytesTotal, downloadSpeedMegSec, timeRemaining) =>
bytesReceived = Number(bytesReceived)
bytesTotal = Number(bytesTotal)
# bytesTotal from Qt is not trust worthy; trust server's answer instead
#progressWidth = ((bytesReceived / updateSize) * 100).toString() + "%";
# $('#progress-bar').width(progressWidth)
downloadSuccessCallback: (updateLocation) =>
# is the package loadable yet?
this.transition(@states.keying)
downloadFailureCallback: (errorMsg) =>
@errorMessage = errorMessage
this.transition(@states.errored)
# makes a function name for the backend
makeDownloadProgressCallback: () =>
"JK.DownloadJamTracks['#{@jamTrackId}'].downloadProgressCallback"
# makes a function name for the backend
makeDownloadSuccessCallback: () =>
"JK.DownloadJamTracks['#{@jamTrackId}'].downloadSuccessCallback"
# makes a function name for the backend
makeDownloadFailureCallback: () =>
"JK.DownloadJamTracks['#{@jamTrackId}'].downloadFailureCallback"

View File

@ -910,6 +910,10 @@
return null;
}
context.JK.makeAbsolute = function(path) {
return window.location.protocol + '//' + window.location.host + path;
}
context.JK.popExternalLinks = function ($parent) {
if(!$parent) $parent = $('body');

View File

@ -33,6 +33,8 @@ class SpikesController < ApplicationController
def subscription
#Notification.send_reload(MessageFactory::ALL_NATIVE_CLIENTS)
Notification.send_subscription_message('test', '1', '{"msg": "oh hai 1"}')
Notification.send_subscription_message('test', '2', '{"msg": "oh hai 2"}')
render text: 'oh hai'

View File

@ -1,2 +1,30 @@
script type="text/template" id='template-download-jamtrack'
.download-jamtrack
script type="text/template" id="template-download-jamtrack-state-no-client"
.state-no-client
| To download this JamTrack, launch the JamKazam application and open it while in a session.
script type="text/template" id="template-download-jamtrack-state-synchronized"
.state-success
| This JamTrack is on your system and ready to play.
script type="text/template" id="template-download-jamtrack-state-packaging"
.state-packaging
| Your JamTrack is currently being created on the JamKazam server.
script type="text/template" id="template-download-jamtrack-state-downloading"
.state-downloading
| Your JamTrack is currently being downloaded.
script type="text/template" id="template-download-jamtrack-state-keying"
.state-keying
| Your JamTrack is being authenticated.
script type="text/template" id="template-download-jamtrack-state-initial"
.state-initial
| Initializing...
script type="text/template" id="template-download-jamtrack-state-errored"
.state-errored
.msg