FeedBunch-app/app/assets/javascripts/ng-services/ng-JobStateSvc.js.coffee.erb
########################################################
# AngularJS service to load the state of background jobs requested by the user
########################################################
angular.module('feedbunch').service 'jobStateSvc',
['$rootScope', '$timeout', '$window', 'csrfTokenSvc', 'loadFeedsSvc', 'timerFlagSvc', 'findSvc', 'favicoSvc', 'userDataSvc',
($rootScope, $timeout, $window, csrfTokenSvc, loadFeedsSvc, timerFlagSvc, findSvc, favicoSvc, userDataSvc)->
# Constants for the different operations the web worker can perform
LOAD_ALL_SUBSCRIBE_JOB_STATES = 'load_all_subscribe_job_states'
LOAD_SINGLE_SUBSCRIBE_JOB_STATE = 'load_single_subscribe_job_state'
DELETE_SUBSCRIBE_JOB_STATE = 'delete_subscribe_job_state'
LOAD_ALL_REFRESH_JOB_STATES = 'load_all_refresh_job_states'
LOAD_SINGLE_REFRESH_JOB_STATE = 'load_single_refresh_job_state'
DELETE_REFRESH_JOB_STATE = 'delete_refresh_job_state'
# CSRF token
token = csrfTokenSvc.get_token()
# Web worker to load or delete the state of jobs
worker = new Worker '<%= asset_path 'workers/job_state_worker' %>'
worker.onmessage = (e) ->
if e.data.status == 200 || e.data.status == 304
if e.data.operation == LOAD_ALL_SUBSCRIBE_JOB_STATES
all_subscribe_job_states_loaded e.data.response
else if e.data.operation == LOAD_SINGLE_SUBSCRIBE_JOB_STATE
single_subscribe_job_state_loaded e.data.response
else if e.data.operation == LOAD_ALL_REFRESH_JOB_STATES
all_refresh_job_states_loaded e.data.response
else if e.data.operation == LOAD_SINGLE_REFRESH_JOB_STATE
single_refresh_job_state_loaded e.data.response
else if e.data.status == 401 || e.data.status == 422
$window.location.href = '/login'
else if e.data.status == 404
if e.data.operation == LOAD_ALL_SUBSCRIBE_JOB_STATES
$rootScope.subscribe_job_states = []
else if e.data.operation == LOAD_ALL_REFRESH_JOB_STATES
$rootScope.refresh_feed_job_states = []
else
if e.data.operation == LOAD_ALL_SUBSCRIBE_JOB_STATES || e.data.operation == LOAD_ALL_REFRESH_JOB_STATES || e.data.operation == LOAD_SINGLE_REFRESH_JOB_STATE
timerFlagSvc.start 'error_loading_job_states'
else if e.data.operation == LOAD_SINGLE_SUBSCRIBE_JOB_STATE
timerFlagSvc.start 'error_subscribing'
$rootScope.$digest()
#---------------------------------------------
# PRIVATE FUNCTION: Operations after all subscribe job states have been loaded
#---------------------------------------------
all_subscribe_job_states_loaded = (response)->
$rootScope.subscribe_job_states = response.slice()
for job_state in response
# Periodically update the state of any running jobs
load_subscribe_job_state job_state.id if job_state.state=="RUNNING"
#---------------------------------------------
# PRIVATE FUNCTION: Operations after a single subscribe job state has been loaded
#---------------------------------------------
single_subscribe_job_state_loaded = (response)->
job = findSvc.find_subscribe_job response.id
if job?
job.state = response.state
if job.state=="RUNNING"
# If job is running, keep periodically updating its state
load_subscribe_job_state job.id
else if job.state=="ERROR"
timerFlagSvc.start 'error_subscribing'
else if job.state=="SUCCESS"
timerFlagSvc.start 'success_subscribe'
job.feed_id = response.feed_id
# Update the total subscribed feeds count
userDataSvc.load_data()
#---------------------------------------------
# PRIVATE FUNCTION: Operations after all refresh job states have been loaded
#---------------------------------------------
all_refresh_job_states_loaded = (response)->
$rootScope.refresh_feed_job_states = response.slice()
for job_state in response
# Periodically update the state of any running jobs
load_refresh_feed_job_state job_state.id if job_state.state=="RUNNING"
#---------------------------------------------
# PRIVATE FUNCTION: Operations after a single refresh job state has been loaded
#---------------------------------------------
single_refresh_job_state_loaded = (response)->
job = findSvc.find_refresh_feed_job response.id
if job?
job.state = response.state
if job.state=="RUNNING"
# If job is running, keep periodically updating its state
load_refresh_feed_job_state job.id
else if job.state=="ERROR"
timerFlagSvc.start 'error_refreshing_feed'
else if job.state=="SUCCESS"
timerFlagSvc.start 'success_refresh_feed'
loadFeedsSvc.load_feed job.feed_id
#---------------------------------------------
# PRIVATE FUNCTION: load state of a single refresh feed job via AJAX.
#
# Receives as argument the id of the job.
#---------------------------------------------
load_refresh_feed_job_state = (job_id)->
# Store running timers in a hash in the root scope
$rootScope.refresh_job_state_timers ||= {}
# Only start a timer to refresh the job state if there isn't a timer already refreshing that job state
timer = $rootScope.refresh_job_state_timers[job_id]
if !timer?
timer = $timeout ->
# Remove this timer from the list so that another update can be scheduled for 5 seconds in the future
delete $rootScope.refresh_job_state_timers[job_id]
worker.postMessage {operation: LOAD_SINGLE_REFRESH_JOB_STATE, token: token, id: job_id}
, 5000
# Store timer so that a second timer for the same job state is not started in the future
$rootScope.refresh_job_state_timers[job_id] = timer
#---------------------------------------------
# PRIVATE FUNCTION: load state of a single subscribe job via AJAX.
#
# Receives as argument the id of the job.
#---------------------------------------------
load_subscribe_job_state = (job_id)->
# Store running timers in a hash in the root scope
$rootScope.subscribe_job_state_timers ||= {}
# Only start a timer to refresh the job state if there isn't a timer already refreshing that job state
timer = $rootScope.subscribe_job_state_timers[job_id]
if !timer?
timer = $timeout ->
# Remove this timer from the list so that another update can be scheduled for 5 seconds in the future
delete $rootScope.subscribe_job_state_timers[job_id]
worker.postMessage {operation: LOAD_SINGLE_SUBSCRIBE_JOB_STATE, token: token, id: job_id}
, 5000
# Store timer so that a second timer for the same job state is not started in the future
$rootScope.subscribe_job_state_timers[job_id] = timer
service =
#---------------------------------------------
# Load job states via AJAX into the root scope
#---------------------------------------------
load_data: ->
worker.postMessage {operation: LOAD_ALL_SUBSCRIBE_JOB_STATES, token: token}
worker.postMessage {operation: LOAD_ALL_REFRESH_JOB_STATES, token: token}
#---------------------------------------------
# Hide a refresh feed job state alert and notify the server via AJAX that it should be deleted
# from the database (it will not appear again).
#---------------------------------------------
hide_refresh_job_alert: (job_state)->
# Remove job state from scope
job_state = findSvc.find_refresh_feed_job job_state.id
if job_state?
index = $rootScope.refresh_feed_job_states.indexOf job_state
$rootScope.refresh_feed_job_states.splice index, 1 if index != -1
# If there is a timer updating this job state, stop it.
if $rootScope.refresh_job_state_timers?
timer = $rootScope.refresh_job_state_timers[job_state.id]
if timer?
$timeout.cancel timer
delete $rootScope.refresh_job_state_timers[job_state.id]
worker.postMessage {operation: DELETE_REFRESH_JOB_STATE, token: token, id: job_state.id}
#---------------------------------------------
# Hide a subscribe job state alert and notify the server via AJAX that it should be deleted
# from the database (it will not appear again).
#---------------------------------------------
hide_subscribe_job_alert: (job_state)->
# Remove job state from scope
job_state = findSvc.find_subscribe_job job_state.id
if job_state?
index = $rootScope.subscribe_job_states.indexOf job_state
$rootScope.subscribe_job_states.splice index, 1 if index != -1
# If there is a timer updating this job state, stop it.
if $rootScope.subscribe_job_state_timers?
timer = $rootScope.subscribe_job_state_timers[job_state.id]
if timer?
$timeout.cancel timer
delete $rootScope.subscribe_job_state_timers[job_state.id]
worker.postMessage {operation: DELETE_SUBSCRIBE_JOB_STATE, token: token, id: job_state.id}
return service
]