Merge branch 'master' into ps-ember-update
Conflicts: assets/scripts/app/models/artifact.coffee assets/scripts/app/store.coffee assets/scripts/app/views/job.coffee assets/scripts/spec/spec_helper.coffee
This commit is contained in:
commit
e02ece9424
92
assets/scripts/lib/travis/chunk_buffer.coffee
Normal file
92
assets/scripts/lib/travis/chunk_buffer.coffee
Normal file
|
@ -0,0 +1,92 @@
|
|||
get = Ember.get
|
||||
|
||||
Travis.ChunkBuffer = Em.ArrayProxy.extend
|
||||
timeout: 5000
|
||||
checkTimeoutFrequency: 1000
|
||||
start: 1
|
||||
next: 1
|
||||
|
||||
init: ->
|
||||
@_super.apply this, arguments
|
||||
|
||||
@lastInsert = 0
|
||||
|
||||
@set('next', @get('start'))
|
||||
|
||||
@checkTimeout()
|
||||
|
||||
if @get('content.length')
|
||||
@get('queue.content').pushObjects @get('content').toArray()
|
||||
|
||||
arrangedContent: (->
|
||||
[]
|
||||
).property('content')
|
||||
|
||||
addObject: (obj) ->
|
||||
@get('content').pushObject(obj)
|
||||
|
||||
removeObject: (obj) ->
|
||||
@get('content').removeObject(obj)
|
||||
|
||||
replaceContent: (idx, amt, objects) ->
|
||||
@get('content').replace(idx, amt, objects)
|
||||
|
||||
queue: (->
|
||||
Em.ArrayProxy.create(Em.SortableMixin,
|
||||
content: []
|
||||
sortProperties: ['number']
|
||||
sortAscending: true
|
||||
)
|
||||
).property()
|
||||
|
||||
contentArrayDidChange: (array, index, removedCount, addedCount) ->
|
||||
@_super.apply this, arguments
|
||||
|
||||
if addedCount
|
||||
queue = @get('queue.content')
|
||||
addedObjects = array.slice(index, index + addedCount)
|
||||
console.log 'Added log parts with numbers:', addedObjects.map( (element) -> get(element, 'number') )+'', 'current', @get('next')
|
||||
queue.pushObjects addedObjects
|
||||
@check()
|
||||
@inserted()
|
||||
|
||||
check: ->
|
||||
queue = @get('queue')
|
||||
next = @get('next')
|
||||
|
||||
arrangedContent = @get('arrangedContent')
|
||||
toPush = []
|
||||
|
||||
while queue.get('firstObject.number') <= next
|
||||
element = queue.shiftObject()
|
||||
if get(element, 'number') == next
|
||||
toPush.pushObject get(element, 'content')
|
||||
next += 1
|
||||
|
||||
if toPush.length
|
||||
arrangedContent.pushObjects toPush
|
||||
|
||||
@set('next', next)
|
||||
|
||||
inserted: ->
|
||||
now = @now()
|
||||
@lastInsert = now
|
||||
|
||||
checkTimeout: ->
|
||||
now = @now()
|
||||
if now - @lastInsert > @get('timeout')
|
||||
@giveUpOnMissingParts()
|
||||
@set 'runLaterId', Ember.run.later(this, @checkTimeout, @get('checkTimeoutFrequency'))
|
||||
|
||||
willDestroy: ->
|
||||
Ember.run.cancel @get('runLaterId')
|
||||
@_super.apply this, arguments
|
||||
|
||||
now: ->
|
||||
(new Date()).getTime()
|
||||
|
||||
giveUpOnMissingParts: ->
|
||||
if number = @get('queue.firstObject.number')
|
||||
console.log 'Giving up on missing parts in the buffer, switching to:', number
|
||||
@set('next', number)
|
||||
@check()
|
|
@ -6,7 +6,6 @@ minispade.require 'app'
|
|||
waits(50)
|
||||
runs ->
|
||||
Travis.reset()
|
||||
|
||||
url = "/#{url}" unless url.match /^\//
|
||||
Travis.__container__.lookup('router:main').handleURL(url)
|
||||
|
||||
|
|
93
assets/scripts/spec/unit/chunk_buffer_spec.coffee
Normal file
93
assets/scripts/spec/unit/chunk_buffer_spec.coffee
Normal file
|
@ -0,0 +1,93 @@
|
|||
createChunk = (number, content) ->
|
||||
Em.Object.create(number: number, content: content)
|
||||
|
||||
describe 'Travis.ChunkBuffer', ->
|
||||
it 'waits for parts to be in order before revealing them', ->
|
||||
buffer = Travis.ChunkBuffer.create(content: [])
|
||||
|
||||
buffer.pushObject createChunk(3, "baz")
|
||||
buffer.pushObject createChunk(2, "bar")
|
||||
|
||||
expect(buffer.get('length')).toEqual(0)
|
||||
|
||||
buffer.pushObject createChunk(1, "foo")
|
||||
|
||||
expect(buffer.get('length')).toEqual(3)
|
||||
|
||||
expect(buffer.toArray()).toEqual(['foo', 'bar', 'baz'])
|
||||
|
||||
it 'ignores a part if it fails to be delivered within timeout', ->
|
||||
buffer = Travis.ChunkBuffer.create(content: [], timeout: 20, checkTimeoutFrequency: 5)
|
||||
|
||||
buffer.pushObject createChunk(3, "baz")
|
||||
|
||||
expect(buffer.get('length')).toEqual(0)
|
||||
|
||||
buffer.pushObject createChunk(1, "foo")
|
||||
|
||||
expect(buffer.get('length')).toEqual(1)
|
||||
|
||||
waits 40
|
||||
runs ->
|
||||
expect(buffer.get('length')).toEqual(2)
|
||||
expect(buffer.toArray()).toEqual(['foo', 'baz'])
|
||||
|
||||
buffer.destroy()
|
||||
|
||||
it 'works correctly when parts are passed as content', ->
|
||||
content = [createChunk(2, 'bar')]
|
||||
|
||||
buffer = Travis.ChunkBuffer.create(content: content)
|
||||
|
||||
expect(buffer.get('length')).toEqual(0)
|
||||
|
||||
buffer.pushObject createChunk(1, "foo")
|
||||
|
||||
expect(buffer.get('length')).toEqual(2)
|
||||
expect(buffer.toArray()).toEqual(['foo', 'bar'])
|
||||
|
||||
it 'works correctly when parts duplicated', ->
|
||||
buffer = Travis.ChunkBuffer.create(content: [])
|
||||
|
||||
buffer.pushObject createChunk(1, "foo")
|
||||
buffer.pushObject createChunk(2, "bar")
|
||||
buffer.pushObject createChunk(3, "baz")
|
||||
|
||||
buffer.pushObject createChunk(2, "bar")
|
||||
buffer.pushObject createChunk(3, "baz")
|
||||
buffer.pushObject createChunk(4, "qux")
|
||||
|
||||
expect(buffer.get('length')).toEqual(4)
|
||||
expect(buffer.toArray()).toEqual(['foo', 'bar', 'baz', 'qux'])
|
||||
|
||||
it 'fires array observers properly', ->
|
||||
changes = []
|
||||
buffer = Travis.ChunkBuffer.create(content: [])
|
||||
|
||||
observer = Em.Object.extend(
|
||||
init: ->
|
||||
@_super.apply this, arguments
|
||||
|
||||
@get('content').addArrayObserver this,
|
||||
willChange: 'arrayWillChange',
|
||||
didChange: 'arrayDidChange'
|
||||
|
||||
arrayWillChange: (->)
|
||||
arrayDidChange: (array, index, removedCount, addedCount) ->
|
||||
changes.pushObject([index, addedCount])
|
||||
).create(content: buffer)
|
||||
|
||||
buffer.pushObject createChunk(2, "baz")
|
||||
|
||||
expect(buffer.get('length')).toEqual(0)
|
||||
expect(changes.length).toEqual(0)
|
||||
|
||||
buffer.pushObject createChunk(1, "foo")
|
||||
|
||||
expect(buffer.get('length')).toEqual(2)
|
||||
expect(changes.length).toEqual(1)
|
||||
expect(changes[0]).toEqual([0, 2])
|
||||
|
||||
it 'sets next to start if start is given at init', ->
|
||||
buffer = Travis.ChunkBuffer.create(content: [], start: 5)
|
||||
expect(buffer.get('next')).toEqual(5)
|
Loading…
Reference in New Issue
Block a user