mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-02-20 17:52:51 +00:00
Use Promise Disposer for lock, + cleanup
This commit is contained in:
parent
685af77007
commit
c2496d30c2
@ -22,7 +22,7 @@ func TestPurge(t *testing.T) {
|
||||
|
||||
if err = os.MkdirAll(dataPath, 0755); err != nil {
|
||||
t.Fatal("Could not create test directory for purge")
|
||||
} else if err = ioutil.WriteFile(dataPath+"/test", []byte("test"), 777); err != nil {
|
||||
} else if err = ioutil.WriteFile(dataPath+"/test", []byte("test"), 0777); err != nil {
|
||||
t.Fatal("Could not create test file for purge")
|
||||
}
|
||||
|
||||
|
@ -42,31 +42,29 @@ func TestPurge(t *testing.T) {
|
||||
appId := config.ApplicationId
|
||||
dataPath := "/resin-data/" + appId
|
||||
|
||||
if err := ioutil.WriteFile(dataPath+"/test", []byte("test"), 777); err != nil {
|
||||
if err := ioutil.WriteFile(dataPath+"/test", []byte("test"), 0777); err != nil {
|
||||
t.Fatal("Could not create test file for purge")
|
||||
} else if request, err := http.NewRequest("POST", supervisorAddress+"/v1/purge?apikey=bananas", strings.NewReader(`{"appId": "`+appId+`"}`)); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
if response, err := http.DefaultClient.Do(request); err != nil {
|
||||
response, err := http.DefaultClient.Do(request)
|
||||
defer response.Body.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if response.StatusCode != http.StatusOK {
|
||||
t.Errorf("Expected 200, got %d", response.StatusCode)
|
||||
defer response.Body.Close()
|
||||
if contents, err := ioutil.ReadAll(response.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
t.Fatalf("Response: %s", contents)
|
||||
}
|
||||
} else {
|
||||
defer response.Body.Close()
|
||||
if contents, err := ioutil.ReadAll(response.Body); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !strings.EqualFold(string(contents), `{"Status":"OK","Error":""}`) {
|
||||
t.Errorf("Purge response didn't match the expected JSON, got: %s", contents)
|
||||
}
|
||||
|
||||
if dirContents, err := ioutil.ReadDir(dataPath); err != nil {
|
||||
t.Errorf("Could not read the data path after purge: %s", err)
|
||||
} else if len(dirContents) > 0 {
|
||||
|
@ -67,21 +67,20 @@ module.exports = (secret) ->
|
||||
utils.mixpanelTrack('Purge /data', appId)
|
||||
if !appId?
|
||||
return res.status(400).send('Missing app id')
|
||||
app = null
|
||||
knex('app').select().where({ appId })
|
||||
.then ([ appFromDB ]) ->
|
||||
if !appFromDB?
|
||||
.then ([ app ]) ->
|
||||
if !app?
|
||||
throw new Error('App not found')
|
||||
app = appFromDB
|
||||
application.lockUpdatesAsync()
|
||||
.tap ->
|
||||
application.kill(app)
|
||||
.then (release) ->
|
||||
request.post config.gosuperAddress + '/v1/purge', { json: true, body: applicationId: appId }, ->
|
||||
application.start(app)
|
||||
Promise.using application.lockUpdates(), ->
|
||||
application.kill(app)
|
||||
.then ->
|
||||
release()
|
||||
.pipe(res)
|
||||
new Promise (resolve, reject) ->
|
||||
request.post(config.gosuperAddress + '/v1/purge', { json: true, body: applicationId: appId })
|
||||
.on 'error', reject
|
||||
.on 'response', -> resolve()
|
||||
.pipe(res)
|
||||
.finally ->
|
||||
application.start(app)
|
||||
.catch (err) ->
|
||||
res.status(503).send(err?.message or err or 'Unknown error')
|
||||
|
||||
|
@ -242,9 +242,10 @@ getEnvironment = do ->
|
||||
console.error("Failed to get environment for device #{deviceId}, app #{appId}. #{err}")
|
||||
throw err
|
||||
|
||||
lock = new Lock()
|
||||
exports.lockUpdates = lockUpdates = lock.async.writeLock
|
||||
exports.lockUpdatesAsync = lockUpdatesAsync = Promise.promisify(lockUpdates)
|
||||
exports.lockUpdates = lockUpdates = do ->
|
||||
_lock = new Lock()
|
||||
_lockUpdates = Promise.promisify(_lock.async.writeLock)
|
||||
return -> _lockUpdates().disposer (release) -> release()
|
||||
|
||||
# 0 - Idle
|
||||
# 1 - Updating
|
||||
@ -325,27 +326,24 @@ exports.update = update = ->
|
||||
app = remoteApps[imageId]
|
||||
fetch(app)
|
||||
.then ->
|
||||
lockUpdatesAsync()
|
||||
.tap ->
|
||||
# Then delete all the ones to remove in one go
|
||||
Promise.map toBeRemoved, (imageId) ->
|
||||
kill(apps[imageId])
|
||||
.tap ->
|
||||
# Then install the apps and add each to the db as they succeed
|
||||
installingPromises = toBeInstalled.map (imageId) ->
|
||||
app = remoteApps[imageId]
|
||||
start(app)
|
||||
# And remove/recreate updated apps and update db as they succeed
|
||||
updatingPromises = toBeUpdated.map (imageId) ->
|
||||
localApp = apps[imageId]
|
||||
app = remoteApps[imageId]
|
||||
logSystemEvent(logTypes.updateApp, app)
|
||||
kill(localApp)
|
||||
Promise.using lockUpdates(), ->
|
||||
# Then delete all the ones to remove in one go
|
||||
Promise.map toBeRemoved, (imageId) ->
|
||||
kill(apps[imageId])
|
||||
.then ->
|
||||
start(app)
|
||||
Promise.all(installingPromises.concat(updatingPromises))
|
||||
.then (release) ->
|
||||
release()
|
||||
# Then install the apps and add each to the db as they succeed
|
||||
installingPromises = toBeInstalled.map (imageId) ->
|
||||
app = remoteApps[imageId]
|
||||
start(app)
|
||||
# And remove/recreate updated apps and update db as they succeed
|
||||
updatingPromises = toBeUpdated.map (imageId) ->
|
||||
localApp = apps[imageId]
|
||||
app = remoteApps[imageId]
|
||||
logSystemEvent(logTypes.updateApp, app)
|
||||
kill(localApp)
|
||||
.then ->
|
||||
start(app)
|
||||
Promise.all(installingPromises.concat(updatingPromises))
|
||||
.then ->
|
||||
failedUpdates = 0
|
||||
# We cleanup here as we want a point when we have a consistent apps/images state, rather than potentially at a
|
||||
|
Loading…
x
Reference in New Issue
Block a user