mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-01-03 04:26:44 +00:00
Fix multiple update loops appearing after a long period of updates failing.
This commit is contained in:
parent
40298f24d6
commit
4ed64536ec
@ -1,3 +1,4 @@
|
|||||||
|
* Fixed multiple update loops appearing after a long period of updates failing. [Page]
|
||||||
* Avoid restarting the app if the device name changes [Pablo]
|
* Avoid restarting the app if the device name changes [Pablo]
|
||||||
* Use appId in dependent app assets tar path, and only create the tar if it doesn't exist [Pablo]
|
* Use appId in dependent app assets tar path, and only create the tar if it doesn't exist [Pablo]
|
||||||
* Support AUFS by upgrading node-docker-delta to 1.0.0 and docker-toolbelt to 1.3.0 [Pablo]
|
* Support AUFS by upgrading node-docker-delta to 1.0.0 and docker-toolbelt to 1.3.0 [Pablo]
|
||||||
|
@ -445,6 +445,7 @@ waitToKill = (app, timeout) ->
|
|||||||
UPDATE_IDLE = 0
|
UPDATE_IDLE = 0
|
||||||
UPDATE_UPDATING = 1
|
UPDATE_UPDATING = 1
|
||||||
UPDATE_REQUIRED = 2
|
UPDATE_REQUIRED = 2
|
||||||
|
UPDATE_SCHEDULED = 3
|
||||||
|
|
||||||
updateStatus =
|
updateStatus =
|
||||||
state: UPDATE_IDLE
|
state: UPDATE_IDLE
|
||||||
@ -582,9 +583,16 @@ compareForUpdate = (localApps, remoteApps) ->
|
|||||||
allAppIds = _.union(localAppIds, remoteAppIds)
|
allAppIds = _.union(localAppIds, remoteAppIds)
|
||||||
return { toBeRemoved, toBeDownloaded, toBeInstalled, toBeUpdated, appsWithUpdatedConfigs, allAppIds }
|
return { toBeRemoved, toBeDownloaded, toBeInstalled, toBeUpdated, appsWithUpdatedConfigs, allAppIds }
|
||||||
|
|
||||||
application.update = update = (force) ->
|
application.update = update = (force, scheduled = false) ->
|
||||||
if updateStatus.state isnt UPDATE_IDLE
|
switch updateStatus.state
|
||||||
# Mark an update required after the current.
|
when UPDATE_SCHEDULED
|
||||||
|
if scheduled isnt true
|
||||||
|
# There's an update scheduled but it isn't this one, so just stop
|
||||||
|
return
|
||||||
|
when UPDATE_IDLE
|
||||||
|
# All good, carry on with the update.
|
||||||
|
else
|
||||||
|
# Mark an update required after the current in-progress update.
|
||||||
updateStatus.forceNext = force
|
updateStatus.forceNext = force
|
||||||
updateStatus.state = UPDATE_REQUIRED
|
updateStatus.state = UPDATE_REQUIRED
|
||||||
return
|
return
|
||||||
@ -680,21 +688,26 @@ application.update = update = (force) ->
|
|||||||
.catch (err) ->
|
.catch (err) ->
|
||||||
updateStatus.failed++
|
updateStatus.failed++
|
||||||
device.setUpdateState(update_failed: true)
|
device.setUpdateState(update_failed: true)
|
||||||
if updateStatus.state is UPDATE_REQUIRED
|
if updateStatus.state in [ UPDATE_REQUIRED, UPDATE_SCHEDULED ]
|
||||||
console.log('Updating failed, but there is already another update scheduled immediately: ', err)
|
console.log('Updating failed, but there is already another update scheduled immediately: ', err)
|
||||||
return
|
return
|
||||||
delayTime = Math.min((2 ** updateStatus.failed) * 500, 30000)
|
delayTime = Math.min((2 ** updateStatus.failed) * 500, 30000)
|
||||||
# If there was an error then schedule another attempt briefly in the future.
|
# If there was an error then schedule another attempt briefly in the future.
|
||||||
console.log('Scheduling another update attempt due to failure: ', delayTime, err)
|
console.log('Scheduling another update attempt due to failure: ', delayTime, err)
|
||||||
setTimeout(update, delayTime, force)
|
setTimeout(update, delayTime, force || updateStatus.forceNext, true)
|
||||||
|
updateStatus.state = UPDATE_SCHEDULED
|
||||||
.finally ->
|
.finally ->
|
||||||
device.updateState(status: 'Idle')
|
switch updateStatus.state
|
||||||
if updateStatus.state is UPDATE_REQUIRED
|
when UPDATE_REQUIRED
|
||||||
# If an update is required then schedule it
|
# If an update is required then schedule it
|
||||||
setTimeout(update, 1, updateStatus.forceNext)
|
setTimeout(update, 1, updateStatus.forceNext, true)
|
||||||
.finally ->
|
updateStatus.state = UPDATE_SCHEDULED
|
||||||
# Set the updating as finished in its own block, so it never has to worry about other code stopping this.
|
when UPDATE_SCHEDULED
|
||||||
|
# Already scheduled, nothing to do here
|
||||||
|
else
|
||||||
updateStatus.state = UPDATE_IDLE
|
updateStatus.state = UPDATE_IDLE
|
||||||
|
device.updateState(status: 'Idle')
|
||||||
|
return
|
||||||
|
|
||||||
listenToEvents = do ->
|
listenToEvents = do ->
|
||||||
appHasDied = {}
|
appHasDied = {}
|
||||||
|
Loading…
Reference in New Issue
Block a user