travis-web/assets/scripts/app/utils/pusher.coffee
Piotr Sarnacki b0b1ef305b Change the way config is stored
On ember-cli config is stored in config/environment.js file and it can be
accessed at any time of app being booted. Till now we were using Travis.config
which was making things hard, because we needed an application instance to get
any config value. This commit moves config to config/environment.js and allows
to access it at any point of loading the app.
2015-01-30 15:29:46 +01:00

169 lines
5.7 KiB
CoffeeScript

config = ENV.config
TravisPusher = (config) ->
@init(config)
this
TravisPusher.prototype.active_channels = []
TravisPusher.prototype.init = (config) ->
Pusher.warn = @warn.bind(this)
Pusher.host = config.host if config.host
@pusher = new Pusher(config.key, encrypted: config.encrypted, disableStats: true)
@callbacksToProcess = []
Visibility.change (e, state) =>
@processSavedCallbacks() if state == 'visible'
setInterval @processSavedCallbacks.bind(this), @processingIntervalWhenHidden
TravisPusher.prototype.subscribeAll = (channels) ->
@subscribe(channel) for channel in channels
TravisPusher.prototype.unsubscribeAll = (channels) ->
@unsubscribe(channel) for channel in channels
TravisPusher.prototype.subscribe = (channel) ->
return unless channel
channel = @prefix(channel)
console.log("subscribing to #{channel}")
unless @pusher?.channel(channel)
@pusher.subscribe(channel).bind_all((event, data) => @receive(event, data))
TravisPusher.prototype.unsubscribe = (channel) ->
return unless channel
channel = @prefix(channel)
console.log("unsubscribing from #{channel}")
@pusher.unsubscribe(channel) if @pusher?.channel(channel)
TravisPusher.prototype.prefix = (channel) ->
if channel.indexOf(@config.pusher.channel_prefix) != 0
"#{@config.pusher.channel_prefix}#{channel}"
else
channel
# process pusher messages in batches every 5 minutes when the page is hidden
TravisPusher.prototype.processingIntervalWhenHidden = 1000 * 60 * 5
TravisPusher.prototype.receive = (event, data) ->
return if event.substr(0, 6) == 'pusher'
data = @normalize(event, data) if data.id
@processWhenVisible =>
# TODO remove job:requeued, once sf-restart-event has been merged
# TODO this also needs to clear logs on build:created if matrix jobs are already loaded
if event == 'job:created' || event == 'job:requeued'
if job = Travis.__container__.lookup('store:main').getById('job', data.job.id)
job.clearLog()
Ember.run.next ->
Travis.receive(event, data)
TravisPusher.prototype.processSavedCallbacks = ->
while callback = @callbacksToProcess.shiftObject()
callback.call(this)
TravisPusher.prototype.processLater = (callback) ->
@callbacksToProcess.pushObject(callback)
TravisPusher.prototype.processWhenVisible = (callback) ->
if Visibility.hidden() && Visibility.isSupported()
@processLater(callback)
else
callback.call(this)
TravisPusher.prototype.normalize = (event, data) ->
switch event
when 'build:started', 'build:finished'
data
when 'job:created', 'job:started', 'job:requeued', 'job:finished', 'job:log', 'job:canceled', 'job:received'
data.queue = data.queue.replace('builds.', '') if data.queue
{ job: data }
when 'worker:added', 'worker:updated', 'worker:removed'
{ worker: data }
when 'annotation:created', 'annotation:updated'
{ annotation: data }
TravisPusher.prototype.warn = (type, object) ->
console.warn(type, object.error) unless @ignoreWarning(type, object.error)
TravisPusher.prototype.ignoreWarning = (type, error) ->
code = error?.data?.code || 0
message = error?.data?.message || ''
@ignoreCode(code) || @ignoreMessage(message)
TravisPusher.prototype.ignoreCode = (code) ->
code == 1006
TravisPusher.prototype.ignoreMessage = (message) ->
message.indexOf('Existing subscription') == 0 or message.indexOf('No current subscription') == 0
Pusher.SockJSTransport.isSupported = -> false if config.pusher.host != 'ws.pusherapp.com'
if config.pro
Pusher.channel_auth_transport = 'bulk_ajax'
Pusher.authorizers.bulk_ajax = (socketId, _callback) ->
channels = Travis.pusher.pusher.channels
channels.callbacks ||= []
name = this.channel.name
names = $.keys(channels.channels)
channels.callbacks.push (auths) ->
_callback(false, auth: auths[name])
unless channels.fetching
channels.fetching = true
Travis.ajax.post Pusher.channel_auth_endpoint, { socket_id: socketId, channels: names }, (data) ->
channels.fetching = false
callback(data.channels) for callback in channels.callbacks
Pusher.getDefaultStrategy = (config) ->
[
[":def", "ws_options", {
hostUnencrypted: config.wsHost + ":" + config.wsPort + (config.pusher.path && "/#{config.pusher.path}" || ''),
hostEncrypted: config.wsHost + ":" + config.wssPort + (config.pusher.path && "/#{config.pusher.path}" || '')
path: config.path
}],
[":def", "sockjs_options", {
hostUnencrypted: config.httpHost + ":" + config.httpPort,
hostEncrypted: config.httpHost + ":" + config.httpsPort
}],
[":def", "timeouts", {
loop: true,
timeout: 15000,
timeoutLimit: 60000
}],
[":def", "ws_manager", [":transport_manager", {
lives: 2,
minPingDelay: 10000,
maxPingDelay: config.activity_timeout
}]],
[":def_transport", "ws", "ws", 3, ":ws_options", ":ws_manager"],
[":def_transport", "flash", "flash", 2, ":ws_options", ":ws_manager"],
[":def_transport", "sockjs", "sockjs", 1, ":sockjs_options"],
[":def", "ws_loop", [":sequential", ":timeouts", ":ws"]],
[":def", "flash_loop", [":sequential", ":timeouts", ":flash"]],
[":def", "sockjs_loop", [":sequential", ":timeouts", ":sockjs"]],
[":def", "strategy",
[":cached", 1800000,
[":first_connected",
[":if", [":is_supported", ":ws"], [
":best_connected_ever", ":ws_loop", [":delayed", 2000, [":sockjs_loop"]]
], [":if", [":is_supported", ":flash"], [
":best_connected_ever", ":flash_loop", [":delayed", 2000, [":sockjs_loop"]]
], [
":sockjs_loop"
]
]]
]
]
]
]