mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-04-16 23:38:52 +00:00
Merge pull request #1021 from mwohlert/instantly-apply-update-on-api-request
Apply targetState immediately after update request
This commit is contained in:
commit
821b5ea071
@ -579,7 +579,7 @@ export class APIBinder {
|
||||
if (isFromApi || !_.isEqual(targetState, this.lastTarget)) {
|
||||
await this.deviceState.setTarget(targetState);
|
||||
this.lastTarget = _.cloneDeep(targetState);
|
||||
this.deviceState.triggerApplyTarget({ force });
|
||||
this.deviceState.triggerApplyTarget({ force, isFromApi });
|
||||
}
|
||||
})
|
||||
.tapCatch(err => {
|
||||
|
@ -129,6 +129,8 @@ module.exports = class DeviceState extends EventEmitter
|
||||
@lastSuccessfulUpdate = null
|
||||
@failedUpdates = 0
|
||||
@applyInProgress = false
|
||||
@applyCancelled = false
|
||||
@cancelDelay = null
|
||||
@lastApplyStart = process.hrtime()
|
||||
@scheduledApply = null
|
||||
@shuttingDown = false
|
||||
@ -676,19 +678,31 @@ module.exports = class DeviceState extends EventEmitter
|
||||
@applyUnblocker?()
|
||||
return
|
||||
|
||||
triggerApplyTarget: ({ force = false, delay = 0, initial = false } = {}) =>
|
||||
triggerApplyTarget: ({ force = false, delay = 0, initial = false, isFromApi = false } = {}) =>
|
||||
if @applyInProgress
|
||||
if !@scheduledApply?
|
||||
if !@scheduledApply? || (isFromApi && @cancelDelay)
|
||||
@scheduledApply = { force, delay }
|
||||
if isFromApi
|
||||
# Cancel promise delay if call came from api to prevent waiting due to backoff
|
||||
@cancelDelay()
|
||||
else
|
||||
# If a delay has been set it's because we need to hold off before applying again,
|
||||
# so we need to respect the maximum delay that has been passed
|
||||
@scheduledApply.delay = Math.max(delay, @scheduledApply.delay)
|
||||
@scheduledApply.force or= force
|
||||
return
|
||||
@applyCancelled = false
|
||||
@applyInProgress = true
|
||||
Promise.delay(delay)
|
||||
new Promise (resolve, reject) =>
|
||||
setTimeout(resolve, delay)
|
||||
@cancelDelay = reject
|
||||
.catch =>
|
||||
@applyCancelled = true
|
||||
.then =>
|
||||
@cancelDelay = null
|
||||
if @applyCancelled
|
||||
log.info('Skipping applyTarget because of a cancellation')
|
||||
return
|
||||
@lastApplyStart = process.hrtime()
|
||||
log.info('Applying target state')
|
||||
@applyTarget({ force, initial })
|
||||
|
@ -290,6 +290,22 @@ describe 'deviceState', ->
|
||||
done()
|
||||
, 5
|
||||
|
||||
it 'cancels current promise applying the target state', (done) ->
|
||||
@deviceState.scheduledApply = { force: false, delay: 100 }
|
||||
@deviceState.applyInProgress = true
|
||||
@deviceState.applyCancelled = false
|
||||
new Promise (resolve, reject) =>
|
||||
setTimeout(resolve, 100000)
|
||||
@deviceState.cancelDelay = reject
|
||||
.catch =>
|
||||
@deviceState.applyCancelled = true
|
||||
.finally =>
|
||||
expect(@deviceState.scheduledApply).to.deep.equal({ force: true, delay: 0 })
|
||||
expect(@deviceState.applyCancelled).to.be.true
|
||||
done()
|
||||
@deviceState.triggerApplyTarget({ force: true, isFromApi: true })
|
||||
|
||||
|
||||
it 'applies the target state for device config'
|
||||
|
||||
it 'applies the target state for applications'
|
||||
|
Loading…
x
Reference in New Issue
Block a user