Merge pull request #845 from balena-io/fix-download-race

Fix a race condition that could cause an unnecessary restart
This commit is contained in:
Pablo Carranza Vélez 2018-12-17 16:33:04 -03:00 committed by GitHub
commit 2a3d8de828
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 25 deletions

View File

@ -906,26 +906,29 @@ module.exports = class ApplicationManager extends EventEmitter
return Promise.reject(new Error("Invalid action #{step.action}"))
@actionExecutors[step.action](step, { force, skipLock })
getRequiredSteps: (currentState, targetState, ignoreImages = false) =>
getExtraStateForComparison: =>
@config.get('localMode').then (localMode) =>
Promise.join(
@images.isCleanupNeeded()
@images.getAvailable(localMode)
@images.getDownloadingImageIds()
@networks.supervisorNetworkReady()
@config.get('delta')
(cleanupNeeded, availableImages, downloading, supervisorNetworkReady, delta) =>
conf = _.mapValues({ delta, localMode }, (v) -> checkTruthy(v))
if conf.localMode
cleanupNeeded = false
@_inferNextSteps(cleanupNeeded, availableImages, downloading, supervisorNetworkReady, currentState, targetState, ignoreImages, conf)
.then (nextSteps) =>
if ignoreImages and _.some(nextSteps, action: 'fetch')
throw new Error('Cannot fetch images while executing an API action')
@proxyvisor.getRequiredSteps(availableImages, downloading, currentState, targetState, nextSteps)
.then (proxyvisorSteps) ->
return nextSteps.concat(proxyvisorSteps)
)
Promise.props({
cleanupNeeded: @images.isCleanupNeeded()
availableImages: @images.getAvailable(localMode)
downloading: @images.getDownloadingImageIds()
supervisorNetworkReady: @networks.supervisorNetworkReady()
delta: @config.get('delta')
localMode
})
getRequiredSteps: (currentState, targetState, extraState, ignoreImages = false) =>
{ cleanupNeeded, availableImages, downloading, supervisorNetworkReady, delta, localMode } = extraState
conf = _.mapValues({ delta, localMode }, (v) -> checkTruthy(v))
if conf.localMode
cleanupNeeded = false
@_inferNextSteps(cleanupNeeded, availableImages, downloading, supervisorNetworkReady, currentState, targetState, ignoreImages, conf)
.then (nextSteps) =>
if ignoreImages and _.some(nextSteps, action: 'fetch')
throw new Error('Cannot fetch images while executing an API action')
@proxyvisor.getRequiredSteps(availableImages, downloading, currentState, targetState, nextSteps)
.then (proxyvisorSteps) ->
return nextSteps.concat(proxyvisorSteps)
serviceNameFromId: (serviceId) =>
@getTargetApps().then (apps) ->

View File

@ -584,17 +584,19 @@ module.exports = class DeviceState extends EventEmitter
@applyBlocker
.then =>
@usingInferStepsLock =>
Promise.join(
@getCurrentForComparison()
@getTarget({ initial, intermediate })
(currentState, targetState) =>
@applications.getExtraStateForComparison()
.then (extraState) =>
Promise.all([
@getCurrentForComparison()
@getTarget({ initial, intermediate })
])
.then ([ currentState, targetState ]) =>
@deviceConfig.getRequiredSteps(currentState, targetState)
.then (deviceConfigSteps) =>
if !_.isEmpty(deviceConfigSteps)
return deviceConfigSteps
else
@applications.getRequiredSteps(currentState, targetState, intermediate)
)
@applications.getRequiredSteps(currentState, targetState, extraState, intermediate)
.then (steps) =>
if _.isEmpty(steps)
@emitAsync('apply-target-state-end', null)